mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 09:12:39 +00:00
56 lines
2.0 KiB
Diff
56 lines
2.0 KiB
Diff
|
From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001
|
||
|
From: Samuel Holland <samuel@sholland.org>
|
||
|
Date: Fri, 27 Jan 2023 10:40:07 +0000
|
||
|
Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads
|
||
|
|
||
|
The SID SRAM on at least some SoCs (A64 and D1) returns different values
|
||
|
when read with bus cycles narrower than 32 bits. This is not immediately
|
||
|
obvious, because memcpy_fromio() uses word-size accesses as long as
|
||
|
enough data is being copied.
|
||
|
|
||
|
The vendor driver always uses 32-bit MMIO reads, so do the same here.
|
||
|
This is faster than the register-based method, which is currently used
|
||
|
as a workaround on A64. And it fixes the values returned on D1, where
|
||
|
the SRAM method was being used.
|
||
|
|
||
|
The special case for the last word is needed to maintain .word_size == 1
|
||
|
for sysfs ABI compatibility, as noted previously in commit de2a3eaea552
|
||
|
("nvmem: sunxi_sid: Optimize register read-out method").
|
||
|
|
||
|
Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant")
|
||
|
Cc: stable@vger.kernel.org
|
||
|
Tested-by: Heiko Stuebner <heiko@sntech.de>
|
||
|
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||
|
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||
|
Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.org
|
||
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||
|
---
|
||
|
drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++-
|
||
|
1 file changed, 14 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/drivers/nvmem/sunxi_sid.c
|
||
|
+++ b/drivers/nvmem/sunxi_sid.c
|
||
|
@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context,
|
||
|
void *val, size_t bytes)
|
||
|
{
|
||
|
struct sunxi_sid *sid = context;
|
||
|
+ u32 word;
|
||
|
|
||
|
- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes);
|
||
|
+ /* .stride = 4 so offset is guaranteed to be aligned */
|
||
|
+ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
|
||
|
+
|
||
|
+ val += round_down(bytes, 4);
|
||
|
+ offset += round_down(bytes, 4);
|
||
|
+ bytes = bytes % 4;
|
||
|
+
|
||
|
+ if (!bytes)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /* Handle any trailing bytes */
|
||
|
+ word = readl_relaxed(sid->base + sid->value_offset + offset);
|
||
|
+ memcpy(val, &word, bytes);
|
||
|
|
||
|
return 0;
|
||
|
}
|