]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
patches for 4.20
authorSasha Levin <sashal@kernel.org>
Mon, 18 Feb 2019 02:07:04 +0000 (21:07 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 18 Feb 2019 02:07:04 +0000 (21:07 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.20/gpio-mxc-move-gpio-noirq-suspend-resume-to-syscore-p.patch [new file with mode: 0644]
queue-4.20/series

diff --git a/queue-4.20/gpio-mxc-move-gpio-noirq-suspend-resume-to-syscore-p.patch b/queue-4.20/gpio-mxc-move-gpio-noirq-suspend-resume-to-syscore-p.patch
new file mode 100644 (file)
index 0000000..6cddc64
--- /dev/null
@@ -0,0 +1,114 @@
+From 29587ead0f02d0a3cd799182c8dee4795db3a942 Mon Sep 17 00:00:00 2001
+From: Anson Huang <anson.huang@nxp.com>
+Date: Sun, 17 Feb 2019 23:05:33 +0100
+Subject: gpio: mxc: move gpio noirq suspend/resume to syscore phase
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+commit 1a5287a3dbc34cd0c02c8f64c9131bd23cdfe2bb upstream.
+
+During noirq suspend/resume phase, GPIO irq could arrive
+and its registers like IMR will be changed by irq handle
+process, to make the GPIO registers exactly when it is
+powered ON after resume, move the GPIO noirq suspend/resume
+callback to syscore suspend/resume phase, local irq is
+disabled at this phase so GPIO registers are atomic.
+
+Fixes: c19fdaeea0aa ("gpio: mxc: add power management support")
+Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Martin Hundebøll <martin@geanix.com>
+Cc: <stable@vger.kernel.org> # 4.19.x+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mxc.c | 41 ++++++++++++++++++++++++-----------------
+ 1 file changed, 24 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
+index 995cf0b9e0b1..2d1dfa1e0745 100644
+--- a/drivers/gpio/gpio-mxc.c
++++ b/drivers/gpio/gpio-mxc.c
+@@ -17,6 +17,7 @@
+ #include <linux/irqchip/chained_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/syscore_ops.h>
+ #include <linux/gpio/driver.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+@@ -550,33 +551,38 @@ static void mxc_gpio_restore_regs(struct mxc_gpio_port *port)
+       writel(port->gpio_saved_reg.dr, port->base + GPIO_DR);
+ }
+-static int __maybe_unused mxc_gpio_noirq_suspend(struct device *dev)
++static int mxc_gpio_syscore_suspend(void)
+ {
+-      struct platform_device *pdev = to_platform_device(dev);
+-      struct mxc_gpio_port *port = platform_get_drvdata(pdev);
++      struct mxc_gpio_port *port;
+-      mxc_gpio_save_regs(port);
+-      clk_disable_unprepare(port->clk);
++      /* walk through all ports */
++      list_for_each_entry(port, &mxc_gpio_ports, node) {
++              mxc_gpio_save_regs(port);
++              clk_disable_unprepare(port->clk);
++      }
+       return 0;
+ }
+-static int __maybe_unused mxc_gpio_noirq_resume(struct device *dev)
++static void mxc_gpio_syscore_resume(void)
+ {
+-      struct platform_device *pdev = to_platform_device(dev);
+-      struct mxc_gpio_port *port = platform_get_drvdata(pdev);
++      struct mxc_gpio_port *port;
+       int ret;
+-      ret = clk_prepare_enable(port->clk);
+-      if (ret)
+-              return ret;
+-      mxc_gpio_restore_regs(port);
+-
+-      return 0;
++      /* walk through all ports */
++      list_for_each_entry(port, &mxc_gpio_ports, node) {
++              ret = clk_prepare_enable(port->clk);
++              if (ret) {
++                      pr_err("mxc: failed to enable gpio clock %d\n", ret);
++                      return;
++              }
++              mxc_gpio_restore_regs(port);
++      }
+ }
+-static const struct dev_pm_ops mxc_gpio_dev_pm_ops = {
+-      SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mxc_gpio_noirq_suspend, mxc_gpio_noirq_resume)
++static struct syscore_ops mxc_gpio_syscore_ops = {
++      .suspend = mxc_gpio_syscore_suspend,
++      .resume = mxc_gpio_syscore_resume,
+ };
+ static struct platform_driver mxc_gpio_driver = {
+@@ -584,7 +590,6 @@ static struct platform_driver mxc_gpio_driver = {
+               .name   = "gpio-mxc",
+               .of_match_table = mxc_gpio_dt_ids,
+               .suppress_bind_attrs = true,
+-              .pm = &mxc_gpio_dev_pm_ops,
+       },
+       .probe          = mxc_gpio_probe,
+       .id_table       = mxc_gpio_devtype,
+@@ -592,6 +597,8 @@ static struct platform_driver mxc_gpio_driver = {
+ static int __init gpio_mxc_init(void)
+ {
++      register_syscore_ops(&mxc_gpio_syscore_ops);
++
+       return platform_driver_register(&mxc_gpio_driver);
+ }
+ subsys_initcall(gpio_mxc_init);
+-- 
+2.19.1
+
index 74c40713776e5b49803bf73c9856fb8faa2c9ab2..d847fca4982bb3ba02c3528ca4024c52c82e4512 100644 (file)
@@ -46,3 +46,4 @@ kvm-sev-fail-kvm_sev_init-if-already-initialized.patch
 cifs-fix-credit-calculations-in-compound-mid-callbac.patch
 cifs-do-not-assume-one-credit-for-async-responses.patch
 cifs-fix-mounts-if-the-client-is-low-on-credits.patch
+gpio-mxc-move-gpio-noirq-suspend-resume-to-syscore-p.patch