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:2.722 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site