nvmem: sunxi_sid: Optimize register read-out method
SID cells are 32-bit aligned, and a multiple of 32 bits in length. The only outlier is the thermal sensor calibration data, which is 16 bits per sensor. However a whole 64 bits is allocated for this purpose, so we could consider it conforming to the rule above. Also, the register read-out method assumes native endian, unlike the direct MMIO method, which assumes big endian. Thus no endian conversion is involved. Under these assumptions, the register read-out method can be slightly optimized. Instead of reading one word then discarding 3 bytes, read the whole word directly into the buffer. However, for reads under 4 bytes or trailing bytes, we still use a scratch buffer to extract the requested bytes. We could go one step further if .word_size was 4, but changing that would affect the sysfs interface's behavior. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9c4adfb5dc
commit
de2a3eaea5
|
@ -115,36 +115,34 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
|
|||
* to be not reliable at all.
|
||||
* Read by the registers instead.
|
||||
*/
|
||||
static int sun8i_sid_read_byte_by_reg(const struct sunxi_sid *sid,
|
||||
const unsigned int offset,
|
||||
u8 *out)
|
||||
{
|
||||
u32 word;
|
||||
int ret;
|
||||
|
||||
ret = sun8i_sid_register_readout(sid, offset & ~0x03, &word);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*out = (word >> ((offset & 0x3) * 8)) & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
struct sunxi_sid *sid = context;
|
||||
u8 *buf = val;
|
||||
u32 word;
|
||||
int ret;
|
||||
|
||||
while (bytes--) {
|
||||
ret = sun8i_sid_read_byte_by_reg(sid, offset++, buf++);
|
||||
/* .stride = 4 so offset is guaranteed to be aligned */
|
||||
while (bytes >= 4) {
|
||||
ret = sun8i_sid_register_readout(sid, offset, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val += 4;
|
||||
offset += 4;
|
||||
bytes -= 4;
|
||||
}
|
||||
|
||||
if (!bytes)
|
||||
return 0;
|
||||
|
||||
/* Handle any trailing bytes */
|
||||
ret = sun8i_sid_register_readout(sid, offset, &word);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(val, &word, bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user