lkml.org 
[lkml]   [2019]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/6] nvmem: sunxi_sid: Optimize register read-out method
Date
From: Chen-Yu Tsai <wens@csie.org>

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>
---
drivers/nvmem/sunxi_sid.c | 38 ++++++++++++++++++--------------------
1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 704c35edf796..15fbfab62595 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -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;
}

--
2.20.1
\
 
 \ /
  Last update: 2019-03-18 08:35    [W:0.854 / U:0.172 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site