]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jan 2020 15:52:11 +0000 (16:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jan 2020 15:52:11 +0000 (16:52 +0100)
added patches:
ata-ahci_brcm-fix-ahci-resources-management.patch
ata-libahci_platform-export-again-ahci_platform_-en-dis-able_phys.patch
gpiolib-fix-up-emulated-open-drain-outputs.patch
tracing-have-the-histogram-compare-functions-convert-to-u64-first.patch

queue-4.9/ata-ahci_brcm-fix-ahci-resources-management.patch [new file with mode: 0644]
queue-4.9/ata-libahci_platform-export-again-ahci_platform_-en-dis-able_phys.patch [new file with mode: 0644]
queue-4.9/gpiolib-fix-up-emulated-open-drain-outputs.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/tracing-have-the-histogram-compare-functions-convert-to-u64-first.patch [new file with mode: 0644]

diff --git a/queue-4.9/ata-ahci_brcm-fix-ahci-resources-management.patch b/queue-4.9/ata-ahci_brcm-fix-ahci-resources-management.patch
new file mode 100644 (file)
index 0000000..97e240f
--- /dev/null
@@ -0,0 +1,223 @@
+From c0cdf2ac4b5bf3e5ef2451ea29fb4104278cdabc Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 10 Dec 2019 10:53:45 -0800
+Subject: ata: ahci_brcm: Fix AHCI resources management
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit c0cdf2ac4b5bf3e5ef2451ea29fb4104278cdabc upstream.
+
+The AHCI resources management within ahci_brcm.c is a little
+convoluted, largely because it historically had a dedicated clock that
+was managed within this file in the downstream tree. Once brough
+upstream though, the clock was left to be managed by libahci_platform.c
+which is entirely appropriate.
+
+This patch series ensures that the AHCI resources are fetched and
+enabled before any register access is done, thus avoiding bus errors on
+platforms which clock gate the controller by default.
+
+As a result we need to re-arrange the suspend() and resume() functions
+in order to avoid accessing registers after the clocks have been turned
+off respectively before the clocks have been turned on. Finally, we can
+refactor brcm_ahci_get_portmask() in order to fetch the number of ports
+from hpriv->mmio which is now accessible without jumping through hoops
+like we used to do.
+
+The commit pointed in the Fixes tag is both old and new enough not to
+require major headaches for backporting of this patch.
+
+Fixes: eba68f829794 ("ata: ahci_brcmstb: rename to support across Broadcom SoC's")
+Cc: stable@vger.kernel.org
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci_brcm.c |  105 ++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 76 insertions(+), 29 deletions(-)
+
+--- a/drivers/ata/ahci_brcm.c
++++ b/drivers/ata/ahci_brcm.c
+@@ -226,19 +226,12 @@ static void brcm_sata_phys_disable(struc
+                       brcm_sata_phy_disable(priv, i);
+ }
+-static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
++static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv,
+                                 struct brcm_ahci_priv *priv)
+ {
+-      void __iomem *ahci;
+-      struct resource *res;
+       u32 impl;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci");
+-      ahci = devm_ioremap_resource(&pdev->dev, res);
+-      if (IS_ERR(ahci))
+-              return 0;
+-
+-      impl = readl(ahci + HOST_PORTS_IMPL);
++      impl = readl(hpriv->mmio + HOST_PORTS_IMPL);
+       if (fls(impl) > SATA_TOP_MAX_PHYS)
+               dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
+@@ -246,9 +239,6 @@ static u32 brcm_ahci_get_portmask(struct
+       else if (!impl)
+               dev_info(priv->dev, "no ports found\n");
+-      devm_iounmap(&pdev->dev, ahci);
+-      devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
+-
+       return impl;
+ }
+@@ -275,11 +265,10 @@ static int brcm_ahci_suspend(struct devi
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct brcm_ahci_priv *priv = hpriv->plat_data;
+-      int ret;
+-      ret = ahci_platform_suspend(dev);
+       brcm_sata_phys_disable(priv);
+-      return ret;
++
++      return ahci_platform_suspend(dev);
+ }
+ static int brcm_ahci_resume(struct device *dev)
+@@ -287,11 +276,44 @@ static int brcm_ahci_resume(struct devic
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct brcm_ahci_priv *priv = hpriv->plat_data;
++      int ret;
++
++      /* Make sure clocks are turned on before re-configuration */
++      ret = ahci_platform_enable_clks(hpriv);
++      if (ret)
++              return ret;
+       brcm_sata_init(priv);
+       brcm_sata_phys_enable(priv);
+       brcm_sata_alpm_init(hpriv);
+-      return ahci_platform_resume(dev);
++
++      /* Since we had to enable clocks earlier on, we cannot use
++       * ahci_platform_resume() as-is since a second call to
++       * ahci_platform_enable_resources() would bump up the resources
++       * (regulators, clocks, PHYs) count artificially so we copy the part
++       * after ahci_platform_enable_resources().
++       */
++      ret = ahci_platform_enable_phys(hpriv);
++      if (ret)
++              goto out_disable_phys;
++
++      ret = ahci_platform_resume_host(dev);
++      if (ret)
++              goto out_disable_platform_phys;
++
++      /* We resumed so update PM runtime state */
++      pm_runtime_disable(dev);
++      pm_runtime_set_active(dev);
++      pm_runtime_enable(dev);
++
++      return 0;
++
++out_disable_platform_phys:
++      ahci_platform_disable_phys(hpriv);
++out_disable_phys:
++      brcm_sata_phys_disable(priv);
++      ahci_platform_disable_clks(hpriv);
++      return ret;
+ }
+ #endif
+@@ -338,37 +360,62 @@ static int brcm_ahci_probe(struct platfo
+               priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
+       }
++      hpriv = ahci_platform_get_resources(pdev);
++      if (IS_ERR(hpriv)) {
++              ret = PTR_ERR(hpriv);
++              goto out_reset;
++      }
++
++      ret = ahci_platform_enable_clks(hpriv);
++      if (ret)
++              goto out_reset;
++
++      /* Must be first so as to configure endianness including that
++       * of the standard AHCI register space.
++       */
+       brcm_sata_init(priv);
+-      priv->port_mask = brcm_ahci_get_portmask(pdev, priv);
+-      if (!priv->port_mask)
+-              return -ENODEV;
++      /* Initializes priv->port_mask which is used below */
++      priv->port_mask = brcm_ahci_get_portmask(hpriv, priv);
++      if (!priv->port_mask) {
++              ret = -ENODEV;
++              goto out_disable_clks;
++      }
++      /* Must be done before ahci_platform_enable_phys() */
+       brcm_sata_phys_enable(priv);
+-      hpriv = ahci_platform_get_resources(pdev);
+-      if (IS_ERR(hpriv))
+-              return PTR_ERR(hpriv);
+       hpriv->plat_data = priv;
+       hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP;
+       brcm_sata_alpm_init(hpriv);
+-      ret = ahci_platform_enable_resources(hpriv);
+-      if (ret)
+-              return ret;
+-
+       if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ)
+               hpriv->flags |= AHCI_HFLAG_NO_NCQ;
++      ret = ahci_platform_enable_phys(hpriv);
++      if (ret)
++              goto out_disable_phys;
++
+       ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
+                                     &ahci_platform_sht);
+       if (ret)
+-              return ret;
++              goto out_disable_platform_phys;
+       dev_info(dev, "Broadcom AHCI SATA3 registered\n");
+       return 0;
++
++out_disable_platform_phys:
++      ahci_platform_disable_phys(hpriv);
++out_disable_phys:
++      brcm_sata_phys_disable(priv);
++out_disable_clks:
++      ahci_platform_disable_clks(hpriv);
++out_reset:
++      if (!IS_ERR_OR_NULL(priv->rcdev))
++              reset_control_assert(priv->rcdev);
++      return ret;
+ }
+ static int brcm_ahci_remove(struct platform_device *pdev)
+@@ -378,12 +425,12 @@ static int brcm_ahci_remove(struct platf
+       struct brcm_ahci_priv *priv = hpriv->plat_data;
+       int ret;
++      brcm_sata_phys_disable(priv);
++
+       ret = ata_platform_remove_one(pdev);
+       if (ret)
+               return ret;
+-      brcm_sata_phys_disable(priv);
+-
+       return 0;
+ }
diff --git a/queue-4.9/ata-libahci_platform-export-again-ahci_platform_-en-dis-able_phys.patch b/queue-4.9/ata-libahci_platform-export-again-ahci_platform_-en-dis-able_phys.patch
new file mode 100644 (file)
index 0000000..a4714aa
--- /dev/null
@@ -0,0 +1,76 @@
+From 84b032dbfdf1c139cd2b864e43959510646975f8 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 10 Dec 2019 10:53:44 -0800
+Subject: ata: libahci_platform: Export again ahci_platform_<en/dis>able_phys()
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit 84b032dbfdf1c139cd2b864e43959510646975f8 upstream.
+
+This reverts commit 6bb86fefa086faba7b60bb452300b76a47cde1a5
+("libahci_platform: Staticize ahci_platform_<en/dis>able_phys()") we are
+going to need ahci_platform_{enable,disable}_phys() in a subsequent
+commit for ahci_brcm.c in order to properly control the PHY
+initialization order.
+
+Also make sure the function prototypes are declared in
+include/linux/ahci_platform.h as a result.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/libahci_platform.c |    6 ++++--
+ include/linux/ahci_platform.h  |    2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/libahci_platform.c
++++ b/drivers/ata/libahci_platform.c
+@@ -46,7 +46,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_ops);
+  * RETURNS:
+  * 0 on success otherwise a negative error code
+  */
+-static int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
++int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
+ {
+       int rc, i;
+@@ -71,6 +71,7 @@ disable_phys:
+       }
+       return rc;
+ }
++EXPORT_SYMBOL_GPL(ahci_platform_enable_phys);
+ /**
+  * ahci_platform_disable_phys - Disable PHYs
+@@ -78,7 +79,7 @@ disable_phys:
+  *
+  * This function disables all PHYs found in hpriv->phys.
+  */
+-static void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
++void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
+ {
+       int i;
+@@ -87,6 +88,7 @@ static void ahci_platform_disable_phys(s
+               phy_exit(hpriv->phys[i]);
+       }
+ }
++EXPORT_SYMBOL_GPL(ahci_platform_disable_phys);
+ /**
+  * ahci_platform_enable_clks - Enable platform clocks
+--- a/include/linux/ahci_platform.h
++++ b/include/linux/ahci_platform.h
+@@ -23,6 +23,8 @@ struct ahci_host_priv;
+ struct platform_device;
+ struct scsi_host_template;
++int ahci_platform_enable_phys(struct ahci_host_priv *hpriv);
++void ahci_platform_disable_phys(struct ahci_host_priv *hpriv);
+ int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
+ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
+ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv);
diff --git a/queue-4.9/gpiolib-fix-up-emulated-open-drain-outputs.patch b/queue-4.9/gpiolib-fix-up-emulated-open-drain-outputs.patch
new file mode 100644 (file)
index 0000000..d73c0ff
--- /dev/null
@@ -0,0 +1,44 @@
+From 256efaea1fdc4e38970489197409a26125ee0aaa Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Sat, 7 Dec 2019 16:20:18 +0000
+Subject: gpiolib: fix up emulated open drain outputs
+
+From: Russell King <rmk+kernel@armlinux.org.uk>
+
+commit 256efaea1fdc4e38970489197409a26125ee0aaa upstream.
+
+gpiolib has a corner case with open drain outputs that are emulated.
+When such outputs are outputting a logic 1, emulation will set the
+hardware to input mode, which will cause gpiod_get_direction() to
+report that it is in input mode. This is different from the behaviour
+with a true open-drain output.
+
+Unify the semantics here.
+
+Cc: <stable@vger.kernel.org>
+Suggested-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpiolib.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -188,6 +188,14 @@ int gpiod_get_direction(struct gpio_desc
+       chip = gpiod_to_chip(desc);
+       offset = gpio_chip_hwgpio(desc);
++      /*
++       * Open drain emulation using input mode may incorrectly report
++       * input here, fix that up.
++       */
++      if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) &&
++          test_bit(FLAG_IS_OUT, &desc->flags))
++              return 0;
++
+       if (!chip->get_direction)
+               return status;
index 262d6bca53edcabe8673404036417b634de042bd..7c5fddc6d703fdb071470893b068d86fdf64b395 100644 (file)
@@ -23,3 +23,7 @@ memcg-account-security-cred-as-well-to-kmemcg.patch
 locks-print-unsigned-ino-in-proc-locks.patch
 dmaengine-fix-access-to-uninitialized-dma_slave_caps.patch
 compat_ioctl-block-handle-persistent-reservations.patch
+ata-libahci_platform-export-again-ahci_platform_-en-dis-able_phys.patch
+ata-ahci_brcm-fix-ahci-resources-management.patch
+gpiolib-fix-up-emulated-open-drain-outputs.patch
+tracing-have-the-histogram-compare-functions-convert-to-u64-first.patch
diff --git a/queue-4.9/tracing-have-the-histogram-compare-functions-convert-to-u64-first.patch b/queue-4.9/tracing-have-the-histogram-compare-functions-convert-to-u64-first.patch
new file mode 100644 (file)
index 0000000..9112c24
--- /dev/null
@@ -0,0 +1,45 @@
+From 106f41f5a302cb1f36c7543fae6a05de12e96fa4 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Wed, 11 Dec 2019 15:44:22 -0500
+Subject: tracing: Have the histogram compare functions convert to u64 first
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 106f41f5a302cb1f36c7543fae6a05de12e96fa4 upstream.
+
+The compare functions of the histogram code would be specific for the size
+of the value being compared (byte, short, int, long long). It would
+reference the value from the array via the type of the compare, but the
+value was stored in a 64 bit number. This is fine for little endian
+machines, but for big endian machines, it would end up comparing zeros or
+all ones (depending on the sign) for anything but 64 bit numbers.
+
+To fix this, first derference the value as a u64 then convert it to the type
+being compared.
+
+Link: http://lkml.kernel.org/r/20191211103557.7bed6928@gandalf.local.home
+
+Cc: stable@vger.kernel.org
+Fixes: 08d43a5fa063e ("tracing: Add lock-free tracing_map")
+Acked-by: Tom Zanussi <zanussi@kernel.org>
+Reported-by: Sven Schnelle <svens@stackframe.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/tracing_map.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/tracing_map.c
++++ b/kernel/trace/tracing_map.c
+@@ -90,8 +90,8 @@ static int tracing_map_cmp_atomic64(void
+ #define DEFINE_TRACING_MAP_CMP_FN(type)                                       \
+ static int tracing_map_cmp_##type(void *val_a, void *val_b)           \
+ {                                                                     \
+-      type a = *(type *)val_a;                                        \
+-      type b = *(type *)val_b;                                        \
++      type a = (type)(*(u64 *)val_a);                                 \
++      type b = (type)(*(u64 *)val_b);                                 \
+                                                                       \
+       return (a > b) ? 1 : ((a < b) ? -1 : 0);                        \
+ }