Fix for OF i2c module aliases, Fix for nvmem on AllWinner H3/H5 SoCs

This commit is contained in:
Peter Robinson 2018-04-12 13:55:49 +01:00 committed by Jeremy Cline
parent fe4ef5f759
commit a81b3eb928
No known key found for this signature in database
GPG Key ID: 9223308FA9B246DB
3 changed files with 208 additions and 0 deletions

131
arm-sunxi-nvmem-fixH3.patch Normal file
View File

@ -0,0 +1,131 @@
From 0ab09d651b5858f9bc7d5f74e725334a661828e0 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Fri, 9 Mar 2018 14:47:17 +0000
Subject: nvmem: sunxi-sid: fix H3 SID controller support
It seems that doing some operation will make the value pre-read on H3
SID controller wrong again, so all operation should be performed by
register.
Change the SID reading to use register only.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/sunxi_sid.c | 71 +++++++++++++++++++++++++++++++++--------------
1 file changed, 50 insertions(+), 21 deletions(-)
diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 99bd54d..26bb637 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -85,13 +85,14 @@ static int sunxi_sid_read(void *context, unsigned int offset,
}
static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
- const unsigned int word)
+ const unsigned int offset,
+ u32 *out)
{
u32 reg_val;
int ret;
/* Set word, lock access, and set read command */
- reg_val = (word & SUN8I_SID_OFFSET_MASK)
+ reg_val = (offset & SUN8I_SID_OFFSET_MASK)
<< SUN8I_SID_OFFSET_SHIFT;
reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ;
writel(reg_val, sid->base + SUN8I_SID_PRCTL);
@@ -101,7 +102,49 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
if (ret)
return ret;
+ if (out)
+ *out = readl(sid->base + SUN8I_SID_RDKEY);
+
writel(0, sid->base + SUN8I_SID_PRCTL);
+
+ return 0;
+}
+
+/*
+ * On Allwinner H3, the value on the 0x200 offset of the SID controller seems
+ * 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;
+ int ret;
+
+ while (bytes--) {
+ ret = sun8i_sid_read_byte_by_reg(sid, offset++, buf++);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -131,26 +174,12 @@ static int sunxi_sid_probe(struct platform_device *pdev)
size = cfg->size;
- if (cfg->need_register_readout) {
- /*
- * H3's SID controller have a bug that the value at 0x200
- * offset is not the correct value when the hardware is reseted.
- * However, after doing a register-based read operation, the
- * value become right.
- * Do a full read operation here, but ignore its value
- * (as it's more fast to read by direct MMIO value than
- * with registers)
- */
- for (i = 0; i < (size >> 2); i++) {
- ret = sun8i_sid_register_readout(sid, i);
- if (ret)
- return ret;
- }
- }
-
econfig.size = size;
econfig.dev = dev;
- econfig.reg_read = sunxi_sid_read;
+ if (cfg->need_register_readout)
+ econfig.reg_read = sun8i_sid_read_by_reg;
+ else
+ econfig.reg_read = sunxi_sid_read;
econfig.priv = sid;
nvmem = nvmem_register(&econfig);
if (IS_ERR(nvmem))
@@ -163,7 +192,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
}
for (i = 0; i < size; i++)
- randomness[i] = sunxi_sid_read_byte(sid, i);
+ econfig.reg_read(sid, i, &randomness[i], 1);
add_device_randomness(randomness, size);
kfree(randomness);
--
cgit v1.1

View File

@ -613,6 +613,12 @@ Patch314: crypto-testmgr-Allow-different-compression-results.patch
Patch315: arm-tegra-fix-nouveau-crash.patch
# https://www.spinics.net/lists/arm-kernel/msg630629.html
Patch316: arm-sunxi-nvmem-fixH3.patch
# Upstream 4.17 back port
Patch317: of-i2c-fix-module-aliases.patch
# Enabling Patches for the RPi3+
Patch320: bcm2837-rpi-initial-support-for-the-3.patch
Patch321: bcm2837-gpio-expander.patch
@ -1895,6 +1901,8 @@ fi
- Patch to fix nouveau on Tegra platforms
- Enable IOMMU on Exynos now upstream does
- Further fix for ThunderX ZIP driver
- Fix for OF i2c module aliases
- Fix for nvmem on AllWinner H3/H5 SoCs
* Mon Apr 09 2018 Jeremy Cline <jeremy@jcline.org>
- Include the KCS IPMI BMC driver that's in F27

View File

@ -0,0 +1,69 @@
From af503716ac1444db61d80cb6d17cfe62929c21df Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Sun, 3 Dec 2017 22:40:50 +0100
Subject: i2c: core: report OF style module alias for devices registered via OF
The buses should honor the firmware interface used to register the device,
but the I2C core reports a MODALIAS of the form i2c:<device> even for I2C
devices registered via OF.
This means that user-space will never get an OF stype uevent MODALIAS even
when the drivers modules contain aliases exported from both the I2C and OF
device ID tables. For example, an Atmel maXTouch Touchscreen registered by
a DT node with compatible "atmel,maxtouch" has the following module alias:
$ cat /sys/class/i2c-adapter/i2c-8/8-004b/modalias
i2c:maxtouch
So udev won't be able to auto-load a module for an OF-only device driver.
Many OF-only drivers duplicate the OF device ID table entries in an I2C ID
table only has a workaround for how the I2C core reports the module alias.
This patch changes the I2C core to report an OF related MODALIAS uevent if
the device was registered via OF. So for the previous example, after this
patch, the reported MODALIAS for the Atmel maXTouch will be the following:
$ cat /sys/class/i2c-adapter/i2c-8/8-004b/modalias
of:NtrackpadT<NULL>Catmel,maxtouch
NOTE: This patch may break out-of-tree drivers that were relying on this
behavior, and only had an I2C device ID table even when the device
was registered via OF. There are no remaining drivers in mainline
that do this, but out-of-tree drivers have to be fixed and define
a proper OF device ID table to have module auto-loading working.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Dmitry Mastykin <mastichi@gmail.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/i2c-core-base.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 5a00bf4..edfc23e4 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -124,6 +124,10 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
struct i2c_client *client = to_i2c_client(dev);
int rc;
+ rc = of_device_uevent_modalias(dev, env);
+ if (rc != -ENODEV)
+ return rc;
+
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
@@ -439,6 +443,10 @@ show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
struct i2c_client *client = to_i2c_client(dev);
int len;
+ len = of_device_modalias(dev, buf, PAGE_SIZE);
+ if (len != -ENODEV)
+ return len;
+
len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
if (len != -ENODEV)
return len;
--
cgit v1.1