Fix for OF i2c module aliases, Fix for nvmem on AllWinner H3/H5 SoCs
This commit is contained in:
parent
fe4ef5f759
commit
a81b3eb928
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue