diff options
author | Peter Robinson <pbrobinson@gmail.com> | 2018-04-12 13:55:49 +0100 |
---|---|---|
committer | Jeremy Cline <jeremy@jcline.org> | 2018-04-12 11:11:10 -0400 |
commit | a81b3eb928702a8eea16448fed716c3099294e1d (patch) | |
tree | a0879008a03eca40cd47c0895a4deb3e9afd111e | |
parent | fe4ef5f7593324482af5bc6a9a216253b4b751c8 (diff) | |
download | kernel-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.patch | 131 | ||||
-rw-r--r-- | kernel.spec | 8 | ||||
-rw-r--r-- | of-i2c-fix-module-aliases.patch | 69 |
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 |