summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Robinson <pbrobinson@gmail.com>2018-04-12 13:55:49 +0100
committerJeremy Cline <jeremy@jcline.org>2018-04-12 11:11:10 -0400
commita81b3eb928702a8eea16448fed716c3099294e1d (patch)
treea0879008a03eca40cd47c0895a4deb3e9afd111e
parentfe4ef5f7593324482af5bc6a9a216253b4b751c8 (diff)
downloadkernel-a81b3eb928702a8eea16448fed716c3099294e1d.tar.gz
kernel-a81b3eb928702a8eea16448fed716c3099294e1d.tar.xz
kernel-a81b3eb928702a8eea16448fed716c3099294e1d.zip
Fix for OF i2c module aliases, Fix for nvmem on AllWinner H3/H5 SoCs
-rw-r--r--arm-sunxi-nvmem-fixH3.patch131
-rw-r--r--kernel.spec8
-rw-r--r--of-i2c-fix-module-aliases.patch69
3 files changed, 208 insertions, 0 deletions
diff --git a/arm-sunxi-nvmem-fixH3.patch b/arm-sunxi-nvmem-fixH3.patch
new file mode 100644
index 000000000..415885d4c
--- /dev/null
+++ b/arm-sunxi-nvmem-fixH3.patch
@@ -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
diff --git a/kernel.spec b/kernel.spec
index ae06e307c..9cb368fac 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -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
diff --git a/of-i2c-fix-module-aliases.patch b/of-i2c-fix-module-aliases.patch
new file mode 100644
index 000000000..3c737f6e8
--- /dev/null
+++ b/of-i2c-fix-module-aliases.patch
@@ -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