Commit graph

56 commits

Author SHA1 Message Date
Laxman Dewangan
6560ffd1cc regmap: fix possible memory corruption in regmap_bulk_read()
The function regmap_bulk_read() calls the regmap_read() for
each register if set of register has volatile and cache is
enabled. In this case, last few register read makes the memory
corruption if the register size is not the size of unsigned int.
The regam_read() takes argument as unsigned int for returning
value and it update the value as
	*val = map->format.parse_val(map->work_buf);
This causes complete 4 bytes (size of unsigned int) to get written.
Now if client pass the memory pointer for value which is equal to the
required size of register count in regmap_bulk_read() then last few
register read actually update the memory beyond passed pointer size.

Avoid this by using local variable for read and then do memcpy()
for actual byte copy to passed pointer based on register size.

I allocated one pointer ptr and take first 16 bytes dump of that
pointer then call regmap_bulk_read() with pointer which is just
on top of this allocated pointer and register count of 128. Here
register size is 1 byte.
The memory trace of last 5 register read are as follows:

[    5.438589] regmap_bulk_read after regamp_read() for register 122
[    5.447421] 0xef993c20 0xef993c00 0x00000000 0x00000001
[    5.467535] regmap_bulk_read after regamp_read() for register 123
[    5.476374] 0xef993c20 0xef993c00 0x00000000 0x00000001
[    5.496425] regmap_bulk_read after regamp_read() for register 124
[    5.505260] 0xef993c20 0xef993c00 0x00000000 0x00000001
[    5.525372] regmap_bulk_read after regamp_read() for register 125
[    5.534205] 0xef993c00 0xef993c00 0x00000000 0x00000001
[    5.554258] regmap_bulk_read after regamp_read() for register 126
[    5.563100] 0xef990000 0xef993c00 0x00000000 0x00000001
[    5.554258] regmap_bulk_read after regamp_read() for register 127
[    5.587108] 0xef000000 0xef993c00 0x00000000 0x00000001

Here it is observed that the memory content at first word started changing
on last 3 regmap_read() and so corruption happened.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-05-09 15:44:11 +01:00
Mark Brown
addfd8a09e Merge remote-tracking branch 'regmap/topic/bulk' into regmap-next 2012-03-14 13:15:48 +00:00
Mark Brown
eae4b51b21 Merge remote-tracking branch 'regmap/topic/introspection' into regmap-next
Simple add/add conflict:
	drivers/base/regmap/regmap.c
2012-03-14 13:15:03 +00:00
Mark Brown
7d9aca39dc Merge remote-tracking branch 'regmap/topic/drivers' into regmap-next
Resolved simple add/add conflicts:
	drivers/base/regmap/internal.h
	drivers/base/regmap/regmap.c
2012-03-14 13:13:25 +00:00
Mark Brown
e1c1c69c8f Merge remote-tracking branches 'regmap/topic/core' and 'regmap/topic/devm' into regmap-next 2012-03-14 13:12:33 +00:00
Stephen Warren
f5d6eba74b regmap: Fix future missing prototype of devres_alloc() and friends
[Fix for breakage which will be introduced during the merge window via
header reworks in another tree, the regmap tree does include device.h
but Paul's tree breaks that.  Reworded subject to reflect -- broonie]

regmap.s uses devres_alloc() and others that are prototyped in device.h.
Include that to solve the following:

drivers/base/regmap/regmap.c: In function 'devm_regmap_init':
drivers/base/regmap/regmap.c:331:2: error: implicit declaration of function 'devres_alloc' [-Werror=implicit-function-declaration]
drivers/base/regmap/regmap.c:338:3: error: implicit declaration of function 'devres_add' [-Werror=implicit-function-declaration]
drivers/base/regmap/regmap.c:340:3: error: implicit declaration of function 'devres_free' [-Werror=implicit-function-declaration]
drivers/base/regmap/regmap.c: In function '_regmap_raw_write':
drivers/base/regmap/regmap.c:421:5: error: implicit declaration of function 'dev_err' [-Werror=implicit-function-declaration]

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-03-11 12:52:44 +00:00
Paul Gortmaker
19694b5ea1 regmap: delete unused module.h from drivers/base/regmap files
Remove unused module.h and/or replace with export.h
as required.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-03-01 11:10:35 +00:00
Mark Brown
b8fb5ab156 regmap: Support raw reads from cached registers
Fall back to a register by register read to do so; most likely we'll be
cache only so the overhead will be low.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-21 19:29:18 +00:00
Mark Brown
aca1e172a1 Merge branch 'topic/patch' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into regmap-drivers 2012-02-20 21:21:33 +00:00
Mark Brown
3bf06a1ad9 Merge branch 'topic/devm' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into regmap-drivers 2012-02-20 21:21:25 +00:00
Mark Brown
a6539c3294 regmap: Allow users to query the size of register values
Generic infrastructure based on top of regmap may want to operate on
blocks of data and therefore find it useful to find the size of the
register values. Provide an accessor operation for this.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-20 21:17:08 +00:00
Mark Brown
7d5e525b9c regmap: Implement support for 32 bit registers and values
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-17 16:26:50 -08:00
Laxman Dewangan
8eaeb21925 regmap: add regmap_bulk_write() for register write
The bulk_write() supports the data transfer to multi
register which takes the data into cpu_endianness format
and does formatting of data to device format before
sending to device.
The transfer can be completed in single transfer or multiple
transfer based on data formatting.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-14 14:03:32 -08:00
Laxman Dewangan
c915719841 regmap: Support for caching in reg_raw_write()
Adding support for caching of data into the
non-volatile register from the call of reg_raw_write().

This will allow the larger block of data write into multiple
register without worrying whether register is cached or not
through reg_raw_write().

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-11 23:03:45 +00:00
Axel Lin
2a14d7d9b7 regmap: Fix kcalloc parameters swapped
The first parameter should be "number of elements" and the second parameter
should be "element size".

Signed-off-by: Axel Lin <axel.lin@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-02-10 11:46:14 +00:00
Mark Brown
c0eb46766d regmap: Implement managed regmap_init()
Save error handling and unwinding code in drivers by providing managed
versions of the regmap init functions, simplifying usage.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-30 21:06:43 +00:00
Wolfram Sang
4191f19792 regmap: if format_write is used, declare all registers as "unreadable"
Using .format_write means, we have a custom function to write to the
chip, but not to read back. Also, mark registers as "not precious" and
"not volatile" which is implicit because we cannot read them. Make those
functions use 'regmap_readable' to reuse the checks done there.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-30 16:23:11 +00:00
Wolfram Sang
c212acccc3 regmap: Properly round reg_bytes and val_bytes
For the upcoming 2/6-format, we don't see debugfs output otherwise,
since the current division results in 0. I'd think 10/14 is broken
currently, too.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-29 21:42:40 +00:00
Wolfram Sang
9aa507505c regmap: Add support for 2/6 register formating
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-27 16:26:03 +00:00
Mark Brown
a24f64a648 regmap: Reset device debugfs when reinitialising the cache
Most of the data exposed via debugfs is for or from the cache so reset
all the debugfs configuration to make sure everything is up to date with
the latest configuration, especially if we're changing cache type.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-26 18:34:49 +00:00
Mark Brown
22f0d90a34 regmap: Support register patch sets
Device manufacturers frequently provide register sequences, usually not
fully documented, to be run at startup in order to provide better defaults
for devices (for example, improving performance in the light of silicon
evaluation). Support such updates by allowing drivers to register update
sets with the core. These updates will be written to the device immediately
and will also be rewritten when the cache is synced.

The assumption is that the reason for resyncing the cache will always be
that the device has been powered off. If this turns out to not be the case
then a separate operation can be provided.

Currently the implementation only allows a single set of updates to be
specified for a device, this could be extended in future.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-23 14:01:18 +00:00
Mark Brown
421e8d2de3 regmap: Reset cache status when reinitialsing the cache
When we reinitialise the cache make sure that we reset the cache access
flags, ensuring that the reinitialised cache is in the default state
which is what callers would and do expect given the function name.

This is particularly likely to cause issues in systems where there was no
cache previously as those systems have cache bypass enabled, as for the
wm8994 driver where this was noticed.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-20 13:49:30 +00:00
Mark Brown
82159ba8e6 regmap: Add support for padding between register and address
Some devices, especially those with high speed control interfaces, require
padding between the register and the data. Support this in the regmap API
by providing a pad_bits configuration parameter.

Only devices with integer byte counts are supported.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2012-01-20 12:15:39 +00:00
Mark Brown
8569d023a0 Merge branch 'topic/cache' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap into regmap-next 2011-12-05 13:18:50 +00:00
Mark Brown
bf31517335 regmap: Allow drivers to reinitialise the register cache at runtime
Sometimes the register map information may change in ways that drivers can
discover at runtime. For example, new revisions of a device may add new
registers. Support runtime discovery by drivers by allowing the register
cache to be reinitialised with a new function regmap_reinit_cache() which
discards the existing cache and creates a new one.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-12-05 13:17:36 +00:00
Mark Brown
018690d33e regmap: Allow regmap_update_bits() users to detect changes
Some users of regmap_update_bits() would like to be able to tell their
users if they actually did an update so provide a variant which also
returns a flag indicating if an update took place. We could return a
tristate in the return value of regmap_update_bits() but this makes the
API more cumbersome to use and doesn't fit with the general zero for
success idiom we have.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-29 20:15:50 +00:00
Mark Brown
052d2cd123 regmap: Do debugfs init before cache init
This allows caches to add custom debugfs files.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-21 19:48:26 +00:00
Mark Brown
d91e8db2c3 regmap: Suppress noop writes in regmap_update_bits()
If the new register value is identical to the original one then suppress
the write to the hardware in regmap_update_bits(), saving some I/O cost.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-20 20:56:38 +00:00
Lars-Peter Clausen
7e5ec63ef5 regmap: Add support for 10/14 register formating
This patch adds support for 10 bits register, 14 bits value type register
formating. This is for example used by the Analog Devices AD5380.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-16 17:34:53 +00:00
Lars-Peter Clausen
19254411db regmap: Try cached read before checking if a hardware read is possible
For some register format types we do not provide a parse_val so we can not do a
hardware read. But a cached read is still possible, so try to read from the
cache first, before checking whether a hardware read is possible. Otherwise the
cache becomes pretty useless for these register types.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-16 17:34:53 +00:00
Lars-Peter Clausen
e5e3b8abed regmap: Move initialization of regcache related fields to regcache_init
Move the initialization regcache related fields of the regmap struct to
regcache_init. This allows us to keep regmap and regcache code better
separated.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-16 17:34:53 +00:00
Lars-Peter Clausen
abbb18fb4a regmap: return ERR_PTR instead of NULL in regmap_init
The regmap_init documentation states that it will either return a pointer to a
valid regmap structure or a ERR_PTR in case of an error. Currently it returns a
NULL pointer in case no bus or no config was given. Since NULL is not a
ERR_PTR a caller might assume that it is a pointer to a valid regmap structure,
so return a ERR_PTR(-EINVAL) instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-14 21:44:45 +00:00
Lars-Peter Clausen
58072cbfc5 regmap: Fix memory leak in regmap_init error path
If regcache initialization fails regmap_init will currently exit without
freeing work_buf.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-10 17:41:20 +00:00
Lars-Peter Clausen
c48a9d7492 regmap: Support some more block operations on cached devices
Commit 10a08d9f ("regmap: Support some block operations on cached devices")
allowed raw read operations without throwing a warning when using caches if
all registers are volatile. This patch does the same for raw write operations.

This is for example useful when loading a firmware in a predefined volatile
region on a chip where we otherwise want registers to be cached.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-09 00:56:52 +00:00
Lars-Peter Clausen
82cd9965c3 regmap: Add helper function for checking if a register range is volatile
We already have the same code for checking whether a register range is volatile
in two different places. Instead of duplicating it once more  add a small helper
function for checking whether a register range is voltaile.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-09 00:56:51 +00:00
Mark Brown
81bf58eb3c Merge branches 'regmap/irq' and 'regmap/cache' into regmap-next 2011-11-08 14:16:06 +00:00
Mark Brown
8ae0d7e8a9 regmap: Track if the register cache is dirty and suppress unneeded syncs
Allow drivers to optimise out the register cache sync if they didn't need
to do one. If the hardware is desynced from the register cache (by power
loss for example) then the driver should call regcache_mark_dirty() to
let the core know about this.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-08 11:38:15 +00:00
Mark Brown
b973aa3624 regmap: Fix typo in kerneldoc for regmap_update_bits()
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-11-08 11:32:55 +00:00
Mark Brown
de2d808f4d regmap: Support some block operations on cached devices
Support raw reads if all the registers being read are volatile, the cache
will have no impact for tem.

Support bulk reads either directly (if all the registers are volatile) or
by falling back to iterating over single register reads otherwise.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-10-13 11:41:54 +01:00
Mark Brown
04e016adca regmap: Warn on raw I/O as well as bulk reads that bypass cache
As with the bulk reads we really should be able to make these play
nicely with the cache but warn for now.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
2011-10-10 10:24:33 +01:00
Dimitris Papastamos
4d2dc09538 regmap: Make _regmap_write() global
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-09-29 11:19:45 +01:00
Dimitris Papastamos
5d1729e7f0 regmap: Incorporate the regcache core into regmap
This patch incorporates the regcache core code into regmap.  All previous
patches have been no-ops essentially up to this point.

The bulk read operation is not supported by regcache at the moment.  This
will be implemented incrementally.

Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Tested-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-09-19 19:06:35 +01:00
Lars-Peter Clausen
6f306441e9 regmap: Add support for device specific write and read flag masks.
Some buses like SPI have no standard notation of read or write operations.
The general scheme here is to set or clear specific bits in the register
address to indicate whether the operation is a read or write. We already
support having a read flag mask per bus, but as there is no standard
the bits which need to be set or cleared differ between devices and vendors,
thus we need a mechanism to specify them per device.

This patch adds two new entries to the regmap_config struct, read_flag_mask and
write_flag_mask. These will be or'ed onto the top byte when doing a read or
write operation. If both masks are empty the device will fallback to the
regmap_bus masks.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-09-05 14:55:57 -07:00
Mark Brown
a7ace561f1 Merge branch 'regmap-linus' into regmap-next 2011-09-05 10:56:57 -07:00
Mark Brown
5204f5e3f5 regmap: Remove bitrotted module_put()s
The conversion to per bus type registration functions means we don't need
to do module_get()s to hold the bus types in memory (their users will link
to them) so we removed all those calls. This left module_put() calls in
the cleanup paths which aren't needed and which cause unbalanced puts if
we ever try to unload anything.

Reported-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-09-05 10:55:58 -07:00
Mark Brown
8de2f081ef regmap: Add functions to check for access on registers
We're going to be using these in quite a few places so factor out the
readable/writable/volatile/precious checks.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-08-14 19:51:11 +09:00
Mark Brown
2efe1642b7 regmap: Skip precious registers when dumping registers via debugfs
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-08-08 15:57:35 +09:00
Mark Brown
31244e396f regmap: Provide register map dump via debugfs
Copy over the read parts of the ASoC debugfs implementation into regmap,
allowing users to see what the register values the device has are at
runtime. The implementation, especially the support for seeking, is
mostly due to Dimitris Papastamos' work in ASoC.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-08-08 15:57:00 +09:00
Mark Brown
93de91245b regmap: Use a local header for API internals
Allowing the implementation to be multi-file.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-08-08 15:56:50 +09:00
Mark Brown
7330478127 regmap: Implement writable register checks
This is mainly intended to be used by devices which can dynamically
block register writes at runtime, for other devices there is usually
limited value.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
2011-08-08 15:56:41 +09:00