+++ /dev/null
-From 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 Mon Sep 17 00:00:00 2001
-From: Daniel Drake <drake@endlessm.com>
-Date: Mon, 11 Sep 2017 14:11:56 +0800
-Subject: pinctrl/amd: save pin registers over suspend/resume
-
-From: Daniel Drake <drake@endlessm.com>
-
-commit 79d2c8bede2c93f9432d7da0bc2f76a195c90fc0 upstream.
-
-The touchpad in the Asus laptop models X505BA/BP and X542BA/BP is
-unresponsive after suspend/resume. The following error appears during
-resume:
-
- i2c_hid i2c-ELAN1300:00: failed to reset device.
-
-The problem here is that i2c_hid does not notice the interrupt being
-generated at this point, because the GPIO is no longer configured
-for interrupts.
-
-Fix this by saving pinctrl-amd pin registers during suspend and
-restoring them at resume time.
-
-Based on code from pinctrl-intel.
-
-Signed-off-by: Daniel Drake <drake@endlessm.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/pinctrl/pinctrl-amd.c | 75 ++++++++++++++++++++++++++++++++++++++++++
- drivers/pinctrl/pinctrl-amd.h | 1
- 2 files changed, 76 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-amd.c
-+++ b/drivers/pinctrl/pinctrl-amd.c
-@@ -32,6 +32,7 @@
- #include <linux/pinctrl/pinconf.h>
- #include <linux/pinctrl/pinconf-generic.h>
-
-+#include "core.h"
- #include "pinctrl-utils.h"
- #include "pinctrl-amd.h"
-
-@@ -708,6 +709,69 @@ static const struct pinconf_ops amd_pinc
- .pin_config_group_set = amd_pinconf_group_set,
- };
-
-+#ifdef CONFIG_PM_SLEEP
-+static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin)
-+{
-+ const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
-+
-+ if (!pd)
-+ return false;
-+
-+ /*
-+ * Only restore the pin if it is actually in use by the kernel (or
-+ * by userspace).
-+ */
-+ if (pd->mux_owner || pd->gpio_owner ||
-+ gpiochip_line_is_irq(&gpio_dev->gc, pin))
-+ return true;
-+
-+ return false;
-+}
-+
-+int amd_gpio_suspend(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
-+ struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
-+ int i;
-+
-+ for (i = 0; i < desc->npins; i++) {
-+ int pin = desc->pins[i].number;
-+
-+ if (!amd_gpio_should_save(gpio_dev, pin))
-+ continue;
-+
-+ gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4);
-+ }
-+
-+ return 0;
-+}
-+
-+int amd_gpio_resume(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
-+ struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
-+ int i;
-+
-+ for (i = 0; i < desc->npins; i++) {
-+ int pin = desc->pins[i].number;
-+
-+ if (!amd_gpio_should_save(gpio_dev, pin))
-+ continue;
-+
-+ writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct dev_pm_ops amd_gpio_pm_ops = {
-+ SET_LATE_SYSTEM_SLEEP_PM_OPS(amd_gpio_suspend,
-+ amd_gpio_resume)
-+};
-+#endif
-+
- static struct pinctrl_desc amd_pinctrl_desc = {
- .pins = kerncz_pins,
- .npins = ARRAY_SIZE(kerncz_pins),
-@@ -747,6 +811,14 @@ static int amd_gpio_probe(struct platfor
- return -EINVAL;
- }
-
-+#ifdef CONFIG_PM_SLEEP
-+ gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
-+ sizeof(*gpio_dev->saved_regs),
-+ GFP_KERNEL);
-+ if (!gpio_dev->saved_regs)
-+ return -ENOMEM;
-+#endif
-+
- gpio_dev->pdev = pdev;
- gpio_dev->gc.direction_input = amd_gpio_direction_input;
- gpio_dev->gc.direction_output = amd_gpio_direction_output;
-@@ -837,6 +909,9 @@ static struct platform_driver amd_gpio_d
- .driver = {
- .name = "amd_gpio",
- .acpi_match_table = ACPI_PTR(amd_gpio_acpi_match),
-+#ifdef CONFIG_PM_SLEEP
-+ .pm = &amd_gpio_pm_ops,
-+#endif
- },
- .probe = amd_gpio_probe,
- .remove = amd_gpio_remove,
---- a/drivers/pinctrl/pinctrl-amd.h
-+++ b/drivers/pinctrl/pinctrl-amd.h
-@@ -95,6 +95,7 @@ struct amd_gpio {
- struct gpio_chip gc;
- struct resource *res;
- struct platform_device *pdev;
-+ u32 *saved_regs;
- };
-
- /* KERNCZ configuration*/
nfsd-fix-general-protection-fault-in-release_lock_stateid.patch
mm-prevent-double-decrease-of-nr_reserved_highatomic.patch
tty-improve-tty_insert_flip_char-fast-path.patch
-pinctrl-amd-save-pin-registers-over-suspend-resume.patch
+tty-improve-tty_insert_flip_char-slow-path.patch
+tty-fix-__tty_insert_flip_char-regression.patch
--- /dev/null
+From 8a5a90a2a477b86a3dc2eaa5a706db9bfdd647ca Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Wed, 2 Aug 2017 13:11:39 +0200
+Subject: tty: fix __tty_insert_flip_char regression
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 8a5a90a2a477b86a3dc2eaa5a706db9bfdd647ca upstream.
+
+Sergey noticed a small but fatal mistake in __tty_insert_flip_char,
+leading to an oops in an interrupt handler when using any serial
+port.
+
+The problem is that I accidentally took the tty_buffer pointer
+before calling __tty_buffer_request_room(), which replaces the
+buffer. This moves the pointer lookup to the right place after
+allocating the new buffer space.
+
+Fixes: 979990c62848 ("tty: improve tty_insert_flip_char() fast path")
+Reported-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Tested-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/tty_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -372,12 +372,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fla
+ */
+ int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag)
+ {
+- struct tty_buffer *tb = port->buf.tail;
++ struct tty_buffer *tb;
+ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
+
+ if (!__tty_buffer_request_room(port, 1, flags))
+ return 0;
+
++ tb = port->buf.tail;
+ if (~tb->flags & TTYB_NORMAL)
+ *flag_buf_ptr(tb, tb->used) = flag;
+ *char_buf_ptr(tb, tb->used++) = ch;
Fixes: c420f167db8c ("kasan: enable stack instrumentation")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/tty_buffer.c | 24 ++++++++++++++++++++++++
--- /dev/null
+From 065ea0a7afd64d6cf3464bdd1d8cd227527e2045 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 20 Jun 2017 23:10:42 +0200
+Subject: tty: improve tty_insert_flip_char() slow path
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 065ea0a7afd64d6cf3464bdd1d8cd227527e2045 upstream.
+
+While working on improving the fast path of tty_insert_flip_char(),
+I noticed that by calling tty_buffer_request_room(), we needlessly
+move to the separate flag buffer mode for the tty, even when all
+characters use TTY_NORMAL as the flag.
+
+This changes the code to call __tty_buffer_request_room() with the
+correct flag, which will then allocate a regular buffer when it rounds
+out of space but no special flags have been used. I'm guessing that
+this is the behavior that Peter Hurley intended when he introduced
+the compacted flip buffers.
+
+Fixes: acc0f67f307f ("tty: Halve flip buffer GFP_ATOMIC memory consumption")
+Cc: Peter Hurley <peter@hurleysoftware.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/tty_buffer.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -375,10 +375,11 @@ int __tty_insert_flip_char(struct tty_po
+ struct tty_buffer *tb = port->buf.tail;
+ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0;
+
+- if (!tty_buffer_request_room(port, 1))
++ if (!__tty_buffer_request_room(port, 1, flags))
+ return 0;
+
+- *flag_buf_ptr(tb, tb->used) = flag;
++ if (~tb->flags & TTYB_NORMAL)
++ *flag_buf_ptr(tb, tb->used) = flag;
+ *char_buf_ptr(tb, tb->used++) = ch;
+
+ return 1;