]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Wed, 30 Nov 2022 02:18:36 +0000 (21:18 -0500)
committerSasha Levin <sashal@kernel.org>
Wed, 30 Nov 2022 02:18:36 +0000 (21:18 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
15 files changed:
queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch [new file with mode: 0644]
queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch [new file with mode: 0644]
queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch [new file with mode: 0644]
queue-5.4/driver-core-add-device-probe-log-helper.patch [new file with mode: 0644]
queue-5.4/firmware-coreboot-register-bus-in-module-init.patch [new file with mode: 0644]
queue-5.4/firmware-google-release-devices-before-unregistering.patch [new file with mode: 0644]
queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch [new file with mode: 0644]
queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch [new file with mode: 0644]
queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch [new file with mode: 0644]
queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch [new file with mode: 0644]
queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch [new file with mode: 0644]
queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch [new file with mode: 0644]
queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch [new file with mode: 0644]

diff --git a/queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch b/queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch
new file mode 100644 (file)
index 0000000..dc3dd1d
--- /dev/null
@@ -0,0 +1,48 @@
+From 55c10382417ab497fafc7ef36381fdbc899046d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 11:00:39 +0800
+Subject: ceph: avoid putting the realm twice when decoding snaps fails
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 51884d153f7ec85e18d607b2467820a90e0f4359 ]
+
+When decoding the snaps fails it maybe leaving the 'first_realm'
+and 'realm' pointing to the same snaprealm memory. And then it'll
+put it twice and could cause random use-after-free, BUG_ON, etc
+issues.
+
+Cc: stable@vger.kernel.org
+Link: https://tracker.ceph.com/issues/57686
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/snap.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
+index f2731f9efc31..97ce1bd13bad 100644
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -694,7 +694,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+       struct ceph_mds_snap_realm *ri;    /* encoded */
+       __le64 *snaps;                     /* encoded */
+       __le64 *prior_parent_snaps;        /* encoded */
+-      struct ceph_snap_realm *realm = NULL;
++      struct ceph_snap_realm *realm;
+       struct ceph_snap_realm *first_realm = NULL;
+       struct ceph_snap_realm *realm_to_rebuild = NULL;
+       int rebuild_snapcs;
+@@ -705,6 +705,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+       dout("update_snap_trace deletion=%d\n", deletion);
+ more:
++      realm = NULL;
+       rebuild_snapcs = 0;
+       ceph_decode_need(&p, e, sizeof(*ri), bad);
+       ri = p;
+-- 
+2.35.1
+
diff --git a/queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch b/queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch
new file mode 100644 (file)
index 0000000..a8048c1
--- /dev/null
@@ -0,0 +1,129 @@
+From d691daac90063d3dbc8944da11201a85a5e3b90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Feb 2022 14:28:33 +0800
+Subject: ceph: do not update snapshot context when there is no new snapshot
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 2e586641c950e7f3e7e008404bd783a466b9b590 ]
+
+We will only track the uppest parent snapshot realm from which we
+need to rebuild the snapshot contexts _downward_ in hierarchy. For
+all the others having no new snapshot we will do nothing.
+
+This fix will avoid calling ceph_queue_cap_snap() on some inodes
+inappropriately. For example, with the code in mainline, suppose there
+are 2 directory hierarchies (with 6 directories total), like this:
+
+/dir_X1/dir_X2/dir_X3/
+/dir_Y1/dir_Y2/dir_Y3/
+
+Firstly, make a snapshot under /dir_X1/dir_X2/.snap/snap_X2, then make a
+root snapshot under /.snap/root_snap. Every time we make snapshots under
+/dir_Y1/..., the kclient will always try to rebuild the snap context for
+snap_X2 realm and finally will always try to queue cap snaps for dir_Y2
+and dir_Y3, which makes no sense.
+
+That's because the snap_X2's seq is 2 and root_snap's seq is 3. So when
+creating a new snapshot under /dir_Y1/... the new seq will be 4, and
+the mds will send the kclient a snapshot backtrace in _downward_
+order: seqs 4, 3.
+
+When ceph_update_snap_trace() is called, it will always rebuild the from
+the last realm, that's the root_snap. So later when rebuilding the snap
+context, the current logic will always cause it to rebuild the snap_X2
+realm and then try to queue cap snaps for all the inodes related in that
+realm, even though it's not necessary.
+
+This is accompanied by a lot of these sorts of dout messages:
+
+    "ceph:  queue_cap_snap 00000000a42b796b nothing dirty|writing"
+
+Fix the logic to avoid this situation.
+
+Also, the 'invalidate' word is not precise here. In actuality, it will
+cause a rebuild of the existing snapshot contexts or just build
+non-existent ones. Rename it to 'rebuild_snapcs'.
+
+URL: https://tracker.ceph.com/issues/44100
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Stable-dep-of: 51884d153f7e ("ceph: avoid putting the realm twice when decoding snaps fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/snap.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
+index e1b9b224fcb2..f2731f9efc31 100644
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -696,7 +696,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+       __le64 *prior_parent_snaps;        /* encoded */
+       struct ceph_snap_realm *realm = NULL;
+       struct ceph_snap_realm *first_realm = NULL;
+-      int invalidate = 0;
++      struct ceph_snap_realm *realm_to_rebuild = NULL;
++      int rebuild_snapcs;
+       int err = -ENOMEM;
+       LIST_HEAD(dirty_realms);
+@@ -704,6 +705,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+       dout("update_snap_trace deletion=%d\n", deletion);
+ more:
++      rebuild_snapcs = 0;
+       ceph_decode_need(&p, e, sizeof(*ri), bad);
+       ri = p;
+       p += sizeof(*ri);
+@@ -727,7 +729,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+       err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent));
+       if (err < 0)
+               goto fail;
+-      invalidate += err;
++      rebuild_snapcs += err;
+       if (le64_to_cpu(ri->seq) > realm->seq) {
+               dout("update_snap_trace updating %llx %p %lld -> %lld\n",
+@@ -752,22 +754,30 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+               if (realm->seq > mdsc->last_snap_seq)
+                       mdsc->last_snap_seq = realm->seq;
+-              invalidate = 1;
++              rebuild_snapcs = 1;
+       } else if (!realm->cached_context) {
+               dout("update_snap_trace %llx %p seq %lld new\n",
+                    realm->ino, realm, realm->seq);
+-              invalidate = 1;
++              rebuild_snapcs = 1;
+       } else {
+               dout("update_snap_trace %llx %p seq %lld unchanged\n",
+                    realm->ino, realm, realm->seq);
+       }
+-      dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino,
+-           realm, invalidate, p, e);
++      dout("done with %llx %p, rebuild_snapcs=%d, %p %p\n", realm->ino,
++           realm, rebuild_snapcs, p, e);
+-      /* invalidate when we reach the _end_ (root) of the trace */
+-      if (invalidate && p >= e)
+-              rebuild_snap_realms(realm, &dirty_realms);
++      /*
++       * this will always track the uppest parent realm from which
++       * we need to rebuild the snapshot contexts _downward_ in
++       * hierarchy.
++       */
++      if (rebuild_snapcs)
++              realm_to_rebuild = realm;
++
++      /* rebuild_snapcs when we reach the _end_ (root) of the trace */
++      if (realm_to_rebuild && p >= e)
++              rebuild_snap_realms(realm_to_rebuild, &dirty_realms);
+       if (!first_realm)
+               first_realm = realm;
+-- 
+2.35.1
+
diff --git a/queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch b/queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch
new file mode 100644 (file)
index 0000000..5da5481
--- /dev/null
@@ -0,0 +1,513 @@
+From 59146f9426b8d038777d8dcb0fd023c6d78d643d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Dec 2019 20:33:00 +0100
+Subject: device.h: move dev_printk()-like functions to dev_printk.h
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit af628aae8640c268938a0c9344b4ec0d102c0a0a ]
+
+device.h has everything and the kitchen sink when it comes to struct
+device things, so split out the printk-specific things to a separate .h
+file to make things easier to maintain and manage over time.
+
+Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
+Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Cc: Saravana Kannan <saravanak@google.com>
+Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20191209193303.1694546-4-gregkh@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/dev_printk.h | 235 +++++++++++++++++++++++++++++++++++++
+ include/linux/device.h     | 217 +---------------------------------
+ 2 files changed, 236 insertions(+), 216 deletions(-)
+ create mode 100644 include/linux/dev_printk.h
+
+diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h
+new file mode 100644
+index 000000000000..5aad06b4ca7b
+--- /dev/null
++++ b/include/linux/dev_printk.h
+@@ -0,0 +1,235 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * dev_printk.h - printk messages helpers for devices
++ *
++ * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
++ * Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
++ * Copyright (c) 2008-2009 Novell Inc.
++ *
++ */
++
++#ifndef _DEVICE_PRINTK_H_
++#define _DEVICE_PRINTK_H_
++
++#include <linux/compiler.h>
++#include <linux/types.h>
++#include <linux/ratelimit.h>
++
++#ifndef dev_fmt
++#define dev_fmt(fmt) fmt
++#endif
++
++struct device;
++
++#ifdef CONFIG_PRINTK
++
++__printf(3, 0) __cold
++int dev_vprintk_emit(int level, const struct device *dev,
++                   const char *fmt, va_list args);
++__printf(3, 4) __cold
++int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
++
++__printf(3, 4) __cold
++void dev_printk(const char *level, const struct device *dev,
++              const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_emerg(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_alert(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_crit(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_err(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_warn(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_notice(const struct device *dev, const char *fmt, ...);
++__printf(2, 3) __cold
++void _dev_info(const struct device *dev, const char *fmt, ...);
++
++#else
++
++static inline __printf(3, 0)
++int dev_vprintk_emit(int level, const struct device *dev,
++                   const char *fmt, va_list args)
++{ return 0; }
++static inline __printf(3, 4)
++int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
++{ return 0; }
++
++static inline void __dev_printk(const char *level, const struct device *dev,
++                              struct va_format *vaf)
++{}
++static inline __printf(3, 4)
++void dev_printk(const char *level, const struct device *dev,
++               const char *fmt, ...)
++{}
++
++static inline __printf(2, 3)
++void _dev_emerg(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_crit(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_alert(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_err(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_warn(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_notice(const struct device *dev, const char *fmt, ...)
++{}
++static inline __printf(2, 3)
++void _dev_info(const struct device *dev, const char *fmt, ...)
++{}
++
++#endif
++
++/*
++ * #defines for all the dev_<level> macros to prefix with whatever
++ * possible use of #define dev_fmt(fmt) ...
++ */
++
++#define dev_emerg(dev, fmt, ...)                                      \
++      _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_crit(dev, fmt, ...)                                               \
++      _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_alert(dev, fmt, ...)                                      \
++      _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_err(dev, fmt, ...)                                                \
++      _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_warn(dev, fmt, ...)                                               \
++      _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_notice(dev, fmt, ...)                                     \
++      _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#define dev_info(dev, fmt, ...)                                               \
++      _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
++
++#if defined(CONFIG_DYNAMIC_DEBUG)
++#define dev_dbg(dev, fmt, ...)                                                \
++      dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
++#elif defined(DEBUG)
++#define dev_dbg(dev, fmt, ...)                                                \
++      dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
++#else
++#define dev_dbg(dev, fmt, ...)                                                \
++({                                                                    \
++      if (0)                                                          \
++              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
++})
++#endif
++
++#ifdef CONFIG_PRINTK
++#define dev_level_once(dev_level, dev, fmt, ...)                      \
++do {                                                                  \
++      static bool __print_once __read_mostly;                         \
++                                                                      \
++      if (!__print_once) {                                            \
++              __print_once = true;                                    \
++              dev_level(dev, fmt, ##__VA_ARGS__);                     \
++      }                                                               \
++} while (0)
++#else
++#define dev_level_once(dev_level, dev, fmt, ...)                      \
++do {                                                                  \
++      if (0)                                                          \
++              dev_level(dev, fmt, ##__VA_ARGS__);                     \
++} while (0)
++#endif
++
++#define dev_emerg_once(dev, fmt, ...)                                 \
++      dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__)
++#define dev_alert_once(dev, fmt, ...)                                 \
++      dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__)
++#define dev_crit_once(dev, fmt, ...)                                  \
++      dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__)
++#define dev_err_once(dev, fmt, ...)                                   \
++      dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__)
++#define dev_warn_once(dev, fmt, ...)                                  \
++      dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__)
++#define dev_notice_once(dev, fmt, ...)                                        \
++      dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__)
++#define dev_info_once(dev, fmt, ...)                                  \
++      dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__)
++#define dev_dbg_once(dev, fmt, ...)                                   \
++      dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__)
++
++#define dev_level_ratelimited(dev_level, dev, fmt, ...)                       \
++do {                                                                  \
++      static DEFINE_RATELIMIT_STATE(_rs,                              \
++                                    DEFAULT_RATELIMIT_INTERVAL,       \
++                                    DEFAULT_RATELIMIT_BURST);         \
++      if (__ratelimit(&_rs))                                          \
++              dev_level(dev, fmt, ##__VA_ARGS__);                     \
++} while (0)
++
++#define dev_emerg_ratelimited(dev, fmt, ...)                          \
++      dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__)
++#define dev_alert_ratelimited(dev, fmt, ...)                          \
++      dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__)
++#define dev_crit_ratelimited(dev, fmt, ...)                           \
++      dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__)
++#define dev_err_ratelimited(dev, fmt, ...)                            \
++      dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
++#define dev_warn_ratelimited(dev, fmt, ...)                           \
++      dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__)
++#define dev_notice_ratelimited(dev, fmt, ...)                         \
++      dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__)
++#define dev_info_ratelimited(dev, fmt, ...)                           \
++      dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
++#if defined(CONFIG_DYNAMIC_DEBUG)
++/* descriptor check is first to prevent flooding with "callbacks suppressed" */
++#define dev_dbg_ratelimited(dev, fmt, ...)                            \
++do {                                                                  \
++      static DEFINE_RATELIMIT_STATE(_rs,                              \
++                                    DEFAULT_RATELIMIT_INTERVAL,       \
++                                    DEFAULT_RATELIMIT_BURST);         \
++      DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);                 \
++      if (DYNAMIC_DEBUG_BRANCH(descriptor) &&                         \
++          __ratelimit(&_rs))                                          \
++              __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt),       \
++                                ##__VA_ARGS__);                       \
++} while (0)
++#elif defined(DEBUG)
++#define dev_dbg_ratelimited(dev, fmt, ...)                            \
++do {                                                                  \
++      static DEFINE_RATELIMIT_STATE(_rs,                              \
++                                    DEFAULT_RATELIMIT_INTERVAL,       \
++                                    DEFAULT_RATELIMIT_BURST);         \
++      if (__ratelimit(&_rs))                                          \
++              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
++} while (0)
++#else
++#define dev_dbg_ratelimited(dev, fmt, ...)                            \
++do {                                                                  \
++      if (0)                                                          \
++              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
++} while (0)
++#endif
++
++#ifdef VERBOSE_DEBUG
++#define dev_vdbg      dev_dbg
++#else
++#define dev_vdbg(dev, fmt, ...)                                               \
++({                                                                    \
++      if (0)                                                          \
++              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
++})
++#endif
++
++/*
++ * dev_WARN*() acts like dev_printk(), but with the key difference of
++ * using WARN/WARN_ONCE to include file/line information and a backtrace.
++ */
++#define dev_WARN(dev, format, arg...) \
++      WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
++
++#define dev_WARN_ONCE(dev, condition, format, arg...) \
++      WARN_ONCE(condition, "%s %s: " format, \
++                      dev_driver_string(dev), dev_name(dev), ## arg)
++
++#endif /* _DEVICE_PRINTK_H_ */
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 3414b5a67b46..ce8b36f34b3f 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -12,6 +12,7 @@
+ #ifndef _DEVICE_H_
+ #define _DEVICE_H_
++#include <linux/dev_printk.h>
+ #include <linux/ioport.h>
+ #include <linux/kobject.h>
+ #include <linux/klist.h>
+@@ -22,7 +23,6 @@
+ #include <linux/mutex.h>
+ #include <linux/pm.h>
+ #include <linux/atomic.h>
+-#include <linux/ratelimit.h>
+ #include <linux/uidgid.h>
+ #include <linux/gfp.h>
+ #include <linux/overflow.h>
+@@ -1655,221 +1655,6 @@ struct device_link *device_link_add(struct device *consumer,
+ void device_link_del(struct device_link *link);
+ void device_link_remove(void *consumer, struct device *supplier);
+-#ifndef dev_fmt
+-#define dev_fmt(fmt) fmt
+-#endif
+-
+-#ifdef CONFIG_PRINTK
+-
+-__printf(3, 0) __cold
+-int dev_vprintk_emit(int level, const struct device *dev,
+-                   const char *fmt, va_list args);
+-__printf(3, 4) __cold
+-int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
+-
+-__printf(3, 4) __cold
+-void dev_printk(const char *level, const struct device *dev,
+-              const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_emerg(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_alert(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_crit(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_err(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_warn(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_notice(const struct device *dev, const char *fmt, ...);
+-__printf(2, 3) __cold
+-void _dev_info(const struct device *dev, const char *fmt, ...);
+-
+-#else
+-
+-static inline __printf(3, 0)
+-int dev_vprintk_emit(int level, const struct device *dev,
+-                   const char *fmt, va_list args)
+-{ return 0; }
+-static inline __printf(3, 4)
+-int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
+-{ return 0; }
+-
+-static inline void __dev_printk(const char *level, const struct device *dev,
+-                              struct va_format *vaf)
+-{}
+-static inline __printf(3, 4)
+-void dev_printk(const char *level, const struct device *dev,
+-               const char *fmt, ...)
+-{}
+-
+-static inline __printf(2, 3)
+-void _dev_emerg(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_crit(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_alert(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_err(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_warn(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_notice(const struct device *dev, const char *fmt, ...)
+-{}
+-static inline __printf(2, 3)
+-void _dev_info(const struct device *dev, const char *fmt, ...)
+-{}
+-
+-#endif
+-
+-/*
+- * #defines for all the dev_<level> macros to prefix with whatever
+- * possible use of #define dev_fmt(fmt) ...
+- */
+-
+-#define dev_emerg(dev, fmt, ...)                                      \
+-      _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_crit(dev, fmt, ...)                                               \
+-      _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_alert(dev, fmt, ...)                                      \
+-      _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_err(dev, fmt, ...)                                                \
+-      _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_warn(dev, fmt, ...)                                               \
+-      _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_notice(dev, fmt, ...)                                     \
+-      _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#define dev_info(dev, fmt, ...)                                               \
+-      _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-
+-#if defined(CONFIG_DYNAMIC_DEBUG)
+-#define dev_dbg(dev, fmt, ...)                                                \
+-      dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#elif defined(DEBUG)
+-#define dev_dbg(dev, fmt, ...)                                                \
+-      dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__)
+-#else
+-#define dev_dbg(dev, fmt, ...)                                                \
+-({                                                                    \
+-      if (0)                                                          \
+-              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
+-})
+-#endif
+-
+-#ifdef CONFIG_PRINTK
+-#define dev_level_once(dev_level, dev, fmt, ...)                      \
+-do {                                                                  \
+-      static bool __print_once __read_mostly;                         \
+-                                                                      \
+-      if (!__print_once) {                                            \
+-              __print_once = true;                                    \
+-              dev_level(dev, fmt, ##__VA_ARGS__);                     \
+-      }                                                               \
+-} while (0)
+-#else
+-#define dev_level_once(dev_level, dev, fmt, ...)                      \
+-do {                                                                  \
+-      if (0)                                                          \
+-              dev_level(dev, fmt, ##__VA_ARGS__);                     \
+-} while (0)
+-#endif
+-
+-#define dev_emerg_once(dev, fmt, ...)                                 \
+-      dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__)
+-#define dev_alert_once(dev, fmt, ...)                                 \
+-      dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__)
+-#define dev_crit_once(dev, fmt, ...)                                  \
+-      dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__)
+-#define dev_err_once(dev, fmt, ...)                                   \
+-      dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__)
+-#define dev_warn_once(dev, fmt, ...)                                  \
+-      dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__)
+-#define dev_notice_once(dev, fmt, ...)                                        \
+-      dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__)
+-#define dev_info_once(dev, fmt, ...)                                  \
+-      dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__)
+-#define dev_dbg_once(dev, fmt, ...)                                   \
+-      dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__)
+-
+-#define dev_level_ratelimited(dev_level, dev, fmt, ...)                       \
+-do {                                                                  \
+-      static DEFINE_RATELIMIT_STATE(_rs,                              \
+-                                    DEFAULT_RATELIMIT_INTERVAL,       \
+-                                    DEFAULT_RATELIMIT_BURST);         \
+-      if (__ratelimit(&_rs))                                          \
+-              dev_level(dev, fmt, ##__VA_ARGS__);                     \
+-} while (0)
+-
+-#define dev_emerg_ratelimited(dev, fmt, ...)                          \
+-      dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__)
+-#define dev_alert_ratelimited(dev, fmt, ...)                          \
+-      dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__)
+-#define dev_crit_ratelimited(dev, fmt, ...)                           \
+-      dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__)
+-#define dev_err_ratelimited(dev, fmt, ...)                            \
+-      dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__)
+-#define dev_warn_ratelimited(dev, fmt, ...)                           \
+-      dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__)
+-#define dev_notice_ratelimited(dev, fmt, ...)                         \
+-      dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__)
+-#define dev_info_ratelimited(dev, fmt, ...)                           \
+-      dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
+-#if defined(CONFIG_DYNAMIC_DEBUG)
+-/* descriptor check is first to prevent flooding with "callbacks suppressed" */
+-#define dev_dbg_ratelimited(dev, fmt, ...)                            \
+-do {                                                                  \
+-      static DEFINE_RATELIMIT_STATE(_rs,                              \
+-                                    DEFAULT_RATELIMIT_INTERVAL,       \
+-                                    DEFAULT_RATELIMIT_BURST);         \
+-      DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);                 \
+-      if (DYNAMIC_DEBUG_BRANCH(descriptor) &&                         \
+-          __ratelimit(&_rs))                                          \
+-              __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt),       \
+-                                ##__VA_ARGS__);                       \
+-} while (0)
+-#elif defined(DEBUG)
+-#define dev_dbg_ratelimited(dev, fmt, ...)                            \
+-do {                                                                  \
+-      static DEFINE_RATELIMIT_STATE(_rs,                              \
+-                                    DEFAULT_RATELIMIT_INTERVAL,       \
+-                                    DEFAULT_RATELIMIT_BURST);         \
+-      if (__ratelimit(&_rs))                                          \
+-              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
+-} while (0)
+-#else
+-#define dev_dbg_ratelimited(dev, fmt, ...)                            \
+-do {                                                                  \
+-      if (0)                                                          \
+-              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
+-} while (0)
+-#endif
+-
+-#ifdef VERBOSE_DEBUG
+-#define dev_vdbg      dev_dbg
+-#else
+-#define dev_vdbg(dev, fmt, ...)                                               \
+-({                                                                    \
+-      if (0)                                                          \
+-              dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
+-})
+-#endif
+-
+-/*
+- * dev_WARN*() acts like dev_printk(), but with the key difference of
+- * using WARN/WARN_ONCE to include file/line information and a backtrace.
+- */
+-#define dev_WARN(dev, format, arg...) \
+-      WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg);
+-
+-#define dev_WARN_ONCE(dev, condition, format, arg...) \
+-      WARN_ONCE(condition, "%s %s: " format, \
+-                      dev_driver_string(dev), dev_name(dev), ## arg)
+-
+ /* Create alias, so I can be autoloaded. */
+ #define MODULE_ALIAS_CHARDEV(major,minor) \
+       MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
+-- 
+2.35.1
+
diff --git a/queue-5.4/driver-core-add-device-probe-log-helper.patch b/queue-5.4/driver-core-add-device-probe-log-helper.patch
new file mode 100644 (file)
index 0000000..d0a265d
--- /dev/null
@@ -0,0 +1,105 @@
+From e4fa76777e32b842ca1a43cf5bbd64ecf2b7edd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2020 16:43:21 +0200
+Subject: driver core: add device probe log helper
+
+From: Andrzej Hajda <a.hajda@samsung.com>
+
+[ Upstream commit a787e5400a1ceeb0ef92d71ec43aeb35b1fa1334 ]
+
+During probe every time driver gets resource it should usually check for
+error printk some message if it is not -EPROBE_DEFER and return the error.
+This pattern is simple but requires adding few lines after any resource
+acquisition code, as a result it is often omitted or implemented only
+partially.
+dev_err_probe helps to replace such code sequences with simple call,
+so code:
+       if (err != -EPROBE_DEFER)
+               dev_err(dev, ...);
+       return err;
+becomes:
+       return dev_err_probe(dev, err, ...);
+
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20200713144324.23654-2-a.hajda@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/core.c    | 42 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/device.h |  3 +++
+ 2 files changed, 45 insertions(+)
+
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 1b016fdd1a75..20bf185d5441 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3399,6 +3399,48 @@ define_dev_printk_level(_dev_info, KERN_INFO);
+ #endif
++/**
++ * dev_err_probe - probe error check and log helper
++ * @dev: the pointer to the struct device
++ * @err: error value to test
++ * @fmt: printf-style format string
++ * @...: arguments as specified in the format string
++ *
++ * This helper implements common pattern present in probe functions for error
++ * checking: print debug or error message depending if the error value is
++ * -EPROBE_DEFER and propagate error upwards.
++ * It replaces code sequence:
++ *    if (err != -EPROBE_DEFER)
++ *            dev_err(dev, ...);
++ *    else
++ *            dev_dbg(dev, ...);
++ *    return err;
++ * with
++ *    return dev_err_probe(dev, err, ...);
++ *
++ * Returns @err.
++ *
++ */
++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
++{
++      struct va_format vaf;
++      va_list args;
++
++      va_start(args, fmt);
++      vaf.fmt = fmt;
++      vaf.va = &args;
++
++      if (err != -EPROBE_DEFER)
++              dev_err(dev, "error %d: %pV", err, &vaf);
++      else
++              dev_dbg(dev, "error %d: %pV", err, &vaf);
++
++      va_end(args);
++
++      return err;
++}
++EXPORT_SYMBOL_GPL(dev_err_probe);
++
+ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
+ {
+       return fwnode && !IS_ERR(fwnode->secondary);
+diff --git a/include/linux/device.h b/include/linux/device.h
+index ce8b36f34b3f..000514b0aaf0 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -1655,6 +1655,9 @@ struct device_link *device_link_add(struct device *consumer,
+ void device_link_del(struct device_link *link);
+ void device_link_remove(void *consumer, struct device *supplier);
++extern __printf(3, 4)
++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...);
++
+ /* Create alias, so I can be autoloaded. */
+ #define MODULE_ALIAS_CHARDEV(major,minor) \
+       MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
+-- 
+2.35.1
+
diff --git a/queue-5.4/firmware-coreboot-register-bus-in-module-init.patch b/queue-5.4/firmware-coreboot-register-bus-in-module-init.patch
new file mode 100644 (file)
index 0000000..c2dceef
--- /dev/null
@@ -0,0 +1,133 @@
+From 30b9127460e12a34ce30ca60b0a3db7f484875a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Oct 2022 18:10:53 -0700
+Subject: firmware: coreboot: Register bus in module init
+
+From: Brian Norris <briannorris@chromium.org>
+
+[ Upstream commit 65946690ed8d972fdb91a74ee75ac0f0f0d68321 ]
+
+The coreboot_table driver registers a coreboot bus while probing a
+"coreboot_table" device representing the coreboot table memory region.
+Probing this device (i.e., registering the bus) is a dependency for the
+module_init() functions of any driver for this bus (e.g.,
+memconsole-coreboot.c / memconsole_driver_init()).
+
+With synchronous probe, this dependency works OK, as the link order in
+the Makefile ensures coreboot_table_driver_init() (and thus,
+coreboot_table_probe()) completes before a coreboot device driver tries
+to add itself to the bus.
+
+With asynchronous probe, however, coreboot_table_probe() may race with
+memconsole_driver_init(), and so we're liable to hit one of these two:
+
+1. coreboot_driver_register() eventually hits "[...] the bus was not
+   initialized.", and the memconsole driver fails to register; or
+2. coreboot_driver_register() gets past #1, but still races with
+   bus_register() and hits some other undefined/crashing behavior (e.g.,
+   in driver_find() [1])
+
+We can resolve this by registering the bus in our initcall, and only
+deferring "device" work (scanning the coreboot memory region and
+creating sub-devices) to probe().
+
+[1] Example failure, using 'driver_async_probe=*' kernel command line:
+
+[    0.114217] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
+...
+[    0.114307] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc1 #63
+[    0.114316] Hardware name: Google Scarlet (DT)
+...
+[    0.114488] Call trace:
+[    0.114494]  _raw_spin_lock+0x34/0x60
+[    0.114502]  kset_find_obj+0x28/0x84
+[    0.114511]  driver_find+0x30/0x50
+[    0.114520]  driver_register+0x64/0x10c
+[    0.114528]  coreboot_driver_register+0x30/0x3c
+[    0.114540]  memconsole_driver_init+0x24/0x30
+[    0.114550]  do_one_initcall+0x154/0x2e0
+[    0.114560]  do_initcall_level+0x134/0x160
+[    0.114571]  do_initcalls+0x60/0xa0
+[    0.114579]  do_basic_setup+0x28/0x34
+[    0.114588]  kernel_init_freeable+0xf8/0x150
+[    0.114596]  kernel_init+0x2c/0x12c
+[    0.114607]  ret_from_fork+0x10/0x20
+[    0.114624] Code: 5280002b 1100054a b900092a f9800011 (885ffc01)
+[    0.114631] ---[ end trace 0000000000000000 ]---
+
+Fixes: b81e3140e412 ("firmware: coreboot: Make bus registration symmetric")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20221019180934.1.If29e167d8a4771b0bf4a39c89c6946ed764817b9@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/google/coreboot_table.c | 37 +++++++++++++++++++-----
+ 1 file changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
+index 0205987a4fd4..568074148f62 100644
+--- a/drivers/firmware/google/coreboot_table.c
++++ b/drivers/firmware/google/coreboot_table.c
+@@ -152,12 +152,8 @@ static int coreboot_table_probe(struct platform_device *pdev)
+       if (!ptr)
+               return -ENOMEM;
+-      ret = bus_register(&coreboot_bus_type);
+-      if (!ret) {
+-              ret = coreboot_table_populate(dev, ptr);
+-              if (ret)
+-                      bus_unregister(&coreboot_bus_type);
+-      }
++      ret = coreboot_table_populate(dev, ptr);
++
+       memunmap(ptr);
+       return ret;
+@@ -172,7 +168,6 @@ static int __cb_dev_unregister(struct device *dev, void *dummy)
+ static int coreboot_table_remove(struct platform_device *pdev)
+ {
+       bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister);
+-      bus_unregister(&coreboot_bus_type);
+       return 0;
+ }
+@@ -202,6 +197,32 @@ static struct platform_driver coreboot_table_driver = {
+               .of_match_table = of_match_ptr(coreboot_of_match),
+       },
+ };
+-module_platform_driver(coreboot_table_driver);
++
++static int __init coreboot_table_driver_init(void)
++{
++      int ret;
++
++      ret = bus_register(&coreboot_bus_type);
++      if (ret)
++              return ret;
++
++      ret = platform_driver_register(&coreboot_table_driver);
++      if (ret) {
++              bus_unregister(&coreboot_bus_type);
++              return ret;
++      }
++
++      return 0;
++}
++
++static void __exit coreboot_table_driver_exit(void)
++{
++      platform_driver_unregister(&coreboot_table_driver);
++      bus_unregister(&coreboot_bus_type);
++}
++
++module_init(coreboot_table_driver_init);
++module_exit(coreboot_table_driver_exit);
++
+ MODULE_AUTHOR("Google, Inc.");
+ MODULE_LICENSE("GPL");
+-- 
+2.35.1
+
diff --git a/queue-5.4/firmware-google-release-devices-before-unregistering.patch b/queue-5.4/firmware-google-release-devices-before-unregistering.patch
new file mode 100644 (file)
index 0000000..aba34e1
--- /dev/null
@@ -0,0 +1,45 @@
+From 2f01cdf0f0f61b1e7f0bf606a2800df6fa890b85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2019 11:19:29 +0100
+Subject: firmware: google: Release devices before unregistering the bus
+
+From: Patrick Rudolph <patrick.rudolph@9elements.com>
+
+[ Upstream commit cae0970ee9c4527f189aac378c50e2f0ed020418 ]
+
+Fix a bug where the kernel module can't be loaded after it has been
+unloaded as the devices are still present and conflicting with the
+to be created coreboot devices.
+
+Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
+Link: https://lore.kernel.org/r/20191118101934.22526-2-patrick.rudolph@9elements.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 65946690ed8d ("firmware: coreboot: Register bus in module init")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/google/coreboot_table.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
+index 8d132e4f008a..0205987a4fd4 100644
+--- a/drivers/firmware/google/coreboot_table.c
++++ b/drivers/firmware/google/coreboot_table.c
+@@ -163,8 +163,15 @@ static int coreboot_table_probe(struct platform_device *pdev)
+       return ret;
+ }
++static int __cb_dev_unregister(struct device *dev, void *dummy)
++{
++      device_unregister(dev);
++      return 0;
++}
++
+ static int coreboot_table_remove(struct platform_device *pdev)
+ {
++      bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister);
+       bus_unregister(&coreboot_bus_type);
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch b/queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch
new file mode 100644 (file)
index 0000000..3703c32
--- /dev/null
@@ -0,0 +1,188 @@
+From ed7b9f25ead4bf22cbd69d366facd3e039102946 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 16:21:10 +0200
+Subject: iio: ms5611: Simplify IO callback parameters
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+[ Upstream commit dc19fa63ad80a636fdbc1a02153d1ab140cb901f ]
+
+The ms5611 passes &indio_dev->dev as a parameter to all its IO callbacks
+only to directly cast the struct device back to struct iio_dev. And the
+struct iio_dev is then only used to get the drivers state struct.
+
+Simplify this a bit by passing the state struct directly. This makes it a
+bit easier to follow what the code is doing.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Link: https://lore.kernel.org/r/20211020142110.7060-1-lars@metafoo.de
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 17f442e7e475 ("iio: pressure: ms5611: fixed value compensation bug")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/pressure/ms5611.h      |  6 +++---
+ drivers/iio/pressure/ms5611_core.c |  7 +++----
+ drivers/iio/pressure/ms5611_i2c.c  | 11 ++++-------
+ drivers/iio/pressure/ms5611_spi.c  | 17 +++++++----------
+ 4 files changed, 17 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h
+index bc06271fa38b..345f3902e3e3 100644
+--- a/drivers/iio/pressure/ms5611.h
++++ b/drivers/iio/pressure/ms5611.h
+@@ -50,9 +50,9 @@ struct ms5611_state {
+       const struct ms5611_osr *pressure_osr;
+       const struct ms5611_osr *temp_osr;
+-      int (*reset)(struct device *dev);
+-      int (*read_prom_word)(struct device *dev, int index, u16 *word);
+-      int (*read_adc_temp_and_pressure)(struct device *dev,
++      int (*reset)(struct ms5611_state *st);
++      int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word);
++      int (*read_adc_temp_and_pressure)(struct ms5611_state *st,
+                                         s32 *temp, s32 *pressure);
+       struct ms5611_chip_info *chip_info;
+diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
+index f5db9fa086f3..29dd648a308c 100644
+--- a/drivers/iio/pressure/ms5611_core.c
++++ b/drivers/iio/pressure/ms5611_core.c
+@@ -85,8 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+       struct ms5611_state *st = iio_priv(indio_dev);
+       for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
+-              ret = st->read_prom_word(&indio_dev->dev,
+-                                       i, &st->chip_info->prom[i]);
++              ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
+               if (ret < 0) {
+                       dev_err(&indio_dev->dev,
+                               "failed to read prom at %d\n", i);
+@@ -108,7 +107,7 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
+       int ret;
+       struct ms5611_state *st = iio_priv(indio_dev);
+-      ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure);
++      ret = st->read_adc_temp_and_pressure(st, temp, pressure);
+       if (ret < 0) {
+               dev_err(&indio_dev->dev,
+                       "failed to read temperature and pressure\n");
+@@ -196,7 +195,7 @@ static int ms5611_reset(struct iio_dev *indio_dev)
+       int ret;
+       struct ms5611_state *st = iio_priv(indio_dev);
+-      ret = st->reset(&indio_dev->dev);
++      ret = st->reset(st);
+       if (ret < 0) {
+               dev_err(&indio_dev->dev, "failed to reset device\n");
+               return ret;
+diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c
+index 8089c59adce5..3175816e657f 100644
+--- a/drivers/iio/pressure/ms5611_i2c.c
++++ b/drivers/iio/pressure/ms5611_i2c.c
+@@ -18,17 +18,15 @@
+ #include "ms5611.h"
+-static int ms5611_i2c_reset(struct device *dev)
++static int ms5611_i2c_reset(struct ms5611_state *st)
+ {
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+-
+       return i2c_smbus_write_byte(st->client, MS5611_RESET);
+ }
+-static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word)
++static int ms5611_i2c_read_prom_word(struct ms5611_state *st, int index,
++                                   u16 *word)
+ {
+       int ret;
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       ret = i2c_smbus_read_word_swapped(st->client,
+                       MS5611_READ_PROM_WORD + (index << 1));
+@@ -55,11 +53,10 @@ static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val)
+       return 0;
+ }
+-static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev,
++static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st,
+                                                s32 *temp, s32 *pressure)
+ {
+       int ret;
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       const struct ms5611_osr *osr = st->temp_osr;
+       ret = i2c_smbus_write_byte(st->client, osr->cmd);
+diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c
+index c3854594cd26..6e9cab61bc32 100644
+--- a/drivers/iio/pressure/ms5611_spi.c
++++ b/drivers/iio/pressure/ms5611_spi.c
+@@ -13,18 +13,17 @@
+ #include "ms5611.h"
+-static int ms5611_spi_reset(struct device *dev)
++static int ms5611_spi_reset(struct ms5611_state *st)
+ {
+       u8 cmd = MS5611_RESET;
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       return spi_write_then_read(st->client, &cmd, 1, NULL, 0);
+ }
+-static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word)
++static int ms5611_spi_read_prom_word(struct ms5611_state *st, int index,
++                                   u16 *word)
+ {
+       int ret;
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1));
+       if (ret < 0)
+@@ -35,11 +34,10 @@ static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word)
+       return 0;
+ }
+-static int ms5611_spi_read_adc(struct device *dev, s32 *val)
++static int ms5611_spi_read_adc(struct ms5611_state *st, s32 *val)
+ {
+       int ret;
+       u8 buf[3] = { MS5611_READ_ADC };
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       ret = spi_write_then_read(st->client, buf, 1, buf, 3);
+       if (ret < 0)
+@@ -50,11 +48,10 @@ static int ms5611_spi_read_adc(struct device *dev, s32 *val)
+       return 0;
+ }
+-static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev,
++static int ms5611_spi_read_adc_temp_and_pressure(struct ms5611_state *st,
+                                                s32 *temp, s32 *pressure)
+ {
+       int ret;
+-      struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
+       const struct ms5611_osr *osr = st->temp_osr;
+       /*
+@@ -66,7 +63,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev,
+               return ret;
+       usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
+-      ret = ms5611_spi_read_adc(dev, temp);
++      ret = ms5611_spi_read_adc(st, temp);
+       if (ret < 0)
+               return ret;
+@@ -76,7 +73,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev,
+               return ret;
+       usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
+-      return ms5611_spi_read_adc(dev, pressure);
++      return ms5611_spi_read_adc(st, pressure);
+ }
+ static int ms5611_spi_probe(struct spi_device *spi)
+-- 
+2.35.1
+
diff --git a/queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch b/queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch
new file mode 100644 (file)
index 0000000..b45d4fc
--- /dev/null
@@ -0,0 +1,173 @@
+From e5edf2aa006a6a4f220d8feda44d567740be7bd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 15:58:20 +0200
+Subject: iio: pressure: ms5611: fixed value compensation bug
+
+From: Mitja Spes <mitja@lxnav.com>
+
+[ Upstream commit 17f442e7e47579d3881fc4d47354eaef09302e6f ]
+
+When using multiple instances of this driver the compensation PROM was
+overwritten by the last initialized sensor. Now each sensor has own PROM
+storage.
+
+Signed-off-by: Mitja Spes <mitja@lxnav.com>
+Fixes: 9690d81a02dc ("iio: pressure: ms5611: add support for MS5607 temperature and pressure sensor")
+Link: https://lore.kernel.org/r/20221021135827.1444793-2-mitja@lxnav.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/pressure/ms5611.h      | 12 +++----
+ drivers/iio/pressure/ms5611_core.c | 51 ++++++++++++++++--------------
+ 2 files changed, 31 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h
+index 345f3902e3e3..5e2d2d4d87b5 100644
+--- a/drivers/iio/pressure/ms5611.h
++++ b/drivers/iio/pressure/ms5611.h
+@@ -25,13 +25,6 @@ enum {
+       MS5607,
+ };
+-struct ms5611_chip_info {
+-      u16 prom[MS5611_PROM_WORDS_NB];
+-
+-      int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
+-                                          s32 *temp, s32 *pressure);
+-};
+-
+ /*
+  * OverSampling Rate descriptor.
+  * Warning: cmd MUST be kept aligned on a word boundary (see
+@@ -50,12 +43,15 @@ struct ms5611_state {
+       const struct ms5611_osr *pressure_osr;
+       const struct ms5611_osr *temp_osr;
++      u16 prom[MS5611_PROM_WORDS_NB];
++
+       int (*reset)(struct ms5611_state *st);
+       int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word);
+       int (*read_adc_temp_and_pressure)(struct ms5611_state *st,
+                                         s32 *temp, s32 *pressure);
+-      struct ms5611_chip_info *chip_info;
++      int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp,
++                                        s32 *pressure);
+       struct regulator *vdd;
+ };
+diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
+index 29dd648a308c..511ebdeafbe4 100644
+--- a/drivers/iio/pressure/ms5611_core.c
++++ b/drivers/iio/pressure/ms5611_core.c
+@@ -85,7 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+       struct ms5611_state *st = iio_priv(indio_dev);
+       for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
+-              ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
++              ret = st->read_prom_word(st, i, &st->prom[i]);
+               if (ret < 0) {
+                       dev_err(&indio_dev->dev,
+                               "failed to read prom at %d\n", i);
+@@ -93,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+               }
+       }
+-      if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
++      if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
+               dev_err(&indio_dev->dev, "PROM integrity check failed\n");
+               return -ENODEV;
+       }
+@@ -114,21 +114,20 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
+               return ret;
+       }
+-      return st->chip_info->temp_and_pressure_compensate(st->chip_info,
+-                                                         temp, pressure);
++      return st->compensate_temp_and_pressure(st, temp, pressure);
+ }
+-static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st,
+                                              s32 *temp, s32 *pressure)
+ {
+       s32 t = *temp, p = *pressure;
+       s64 off, sens, dt;
+-      dt = t - (chip_info->prom[5] << 8);
+-      off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
+-      sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
++      dt = t - (st->prom[5] << 8);
++      off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
++      sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
+-      t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++      t = 2000 + ((st->prom[6] * dt) >> 23);
+       if (t < 2000) {
+               s64 off2, sens2, t2;
+@@ -154,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf
+       return 0;
+ }
+-static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st,
+                                              s32 *temp, s32 *pressure)
+ {
+       s32 t = *temp, p = *pressure;
+       s64 off, sens, dt;
+-      dt = t - (chip_info->prom[5] << 8);
+-      off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
+-      sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
++      dt = t - (st->prom[5] << 8);
++      off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6);
++      sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7);
+-      t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++      t = 2000 + ((st->prom[6] * dt) >> 23);
+       if (t < 2000) {
+               s64 off2, sens2, t2, tmp;
+@@ -342,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
+ static const unsigned long ms5611_scan_masks[] = {0x3, 0};
+-static struct ms5611_chip_info chip_info_tbl[] = {
+-      [MS5611] = {
+-              .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
+-      },
+-      [MS5607] = {
+-              .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
+-      }
+-};
+-
+ static const struct iio_chan_spec ms5611_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+@@ -433,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
+       struct ms5611_state *st = iio_priv(indio_dev);
+       mutex_init(&st->lock);
+-      st->chip_info = &chip_info_tbl[type];
++
++      switch (type) {
++      case MS5611:
++              st->compensate_temp_and_pressure =
++                      ms5611_temp_and_pressure_compensate;
++              break;
++      case MS5607:
++              st->compensate_temp_and_pressure =
++                      ms5607_temp_and_pressure_compensate;
++              break;
++      default:
++              return -EINVAL;
++      }
++
+       st->temp_osr =
+               &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
+       st->pressure_osr =
+-- 
+2.35.1
+
diff --git a/queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch b/queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch
new file mode 100644 (file)
index 0000000..22a77eb
--- /dev/null
@@ -0,0 +1,50 @@
+From a4129775c6479663ad5f5cbbdc61517bfe03530c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 17:44:22 +0100
+Subject: jbd2: Drop pointless wakeup from jbd2_journal_stop()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 5559b2d81b51de75cb7864bb1fbb82982f7e8fff ]
+
+When we drop last handle from a transaction and journal->j_barrier_count
+> 0, jbd2_journal_stop() wakes up journal->j_wait_transaction_locked
+wait queue. This looks pointless - wait for outstanding handles always
+happens on journal->j_wait_updates waitqueue.
+journal->j_wait_transaction_locked is used to wait for transaction state
+changes and by start_this_handle() for waiting until
+journal->j_barrier_count drops to 0. The first case is clearly
+irrelevant here since only jbd2 thread changes transaction state. The
+second case looks related but jbd2_journal_unlock_updates() is
+responsible for the wakeup in this case. So just drop the wakeup.
+
+Reviewed-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20191105164437.32602-16-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index ce66dbbf0f90..6d78648392f0 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1850,11 +1850,8 @@ int jbd2_journal_stop(handle_t *handle)
+        * once we do this, we must not dereference transaction
+        * pointer again.
+        */
+-      if (atomic_dec_and_test(&transaction->t_updates)) {
++      if (atomic_dec_and_test(&transaction->t_updates))
+               wake_up(&journal->j_wait_updates);
+-              if (journal->j_barrier_count)
+-                      wake_up(&journal->j_wait_transaction_locked);
+-      }
+       rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
+-- 
+2.35.1
+
diff --git a/queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch b/queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch
new file mode 100644 (file)
index 0000000..375fa03
--- /dev/null
@@ -0,0 +1,205 @@
+From 598c77a12e153e9e93ccd16bd289141f0eea4a9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 17:44:23 +0100
+Subject: jbd2: Factor out common parts of stopping and restarting a handle
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit ec8b6f600e49dc87a8564807fec4193bf93ee2b5 ]
+
+jbd2__journal_restart() has quite some code that is common with
+jbd2_journal_stop(). Factor this functionality into stop_this_handle()
+helper and use it from both functions. Note that this also drops
+t_handle_lock protection from jbd2__journal_restart() as
+jbd2_journal_stop() does the same thing without it.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20191105164437.32602-17-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 98 ++++++++++++++++++++-----------------------
+ 1 file changed, 46 insertions(+), 52 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 6d78648392f0..ee9a778c8fbe 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -514,12 +514,17 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
+ }
+ EXPORT_SYMBOL(jbd2_journal_start);
+-void jbd2_journal_free_reserved(handle_t *handle)
++static void __jbd2_journal_unreserve_handle(handle_t *handle)
+ {
+       journal_t *journal = handle->h_journal;
+       WARN_ON(!handle->h_reserved);
+       sub_reserved_credits(journal, handle->h_buffer_credits);
++}
++
++void jbd2_journal_free_reserved(handle_t *handle)
++{
++      __jbd2_journal_unreserve_handle(handle);
+       jbd2_free_handle(handle);
+ }
+ EXPORT_SYMBOL(jbd2_journal_free_reserved);
+@@ -657,6 +662,28 @@ int jbd2_journal_extend(handle_t *handle, int nblocks)
+       return result;
+ }
++static void stop_this_handle(handle_t *handle)
++{
++      transaction_t *transaction = handle->h_transaction;
++      journal_t *journal = transaction->t_journal;
++
++      J_ASSERT(journal_current_handle() == handle);
++      J_ASSERT(atomic_read(&transaction->t_updates) > 0);
++      current->journal_info = NULL;
++      atomic_sub(handle->h_buffer_credits,
++                 &transaction->t_outstanding_credits);
++      if (handle->h_rsv_handle)
++              __jbd2_journal_unreserve_handle(handle->h_rsv_handle);
++      if (atomic_dec_and_test(&transaction->t_updates))
++              wake_up(&journal->j_wait_updates);
++
++      rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
++      /*
++       * Scope of the GFP_NOFS context is over here and so we can restore the
++       * original alloc context.
++       */
++      memalloc_nofs_restore(handle->saved_alloc_context);
++}
+ /**
+  * int jbd2_journal_restart() - restart a handle .
+@@ -679,52 +706,34 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal;
+       tid_t           tid;
+-      int             need_to_start, ret;
++      int             need_to_start;
+       /* If we've had an abort of any type, don't even think about
+        * actually doing the restart! */
+       if (is_handle_aborted(handle))
+               return 0;
+       journal = transaction->t_journal;
++      tid = transaction->t_tid;
+       /*
+        * First unlink the handle from its current transaction, and start the
+        * commit on that.
+        */
+-      J_ASSERT(atomic_read(&transaction->t_updates) > 0);
+-      J_ASSERT(journal_current_handle() == handle);
+-
+-      read_lock(&journal->j_state_lock);
+-      spin_lock(&transaction->t_handle_lock);
+-      atomic_sub(handle->h_buffer_credits,
+-                 &transaction->t_outstanding_credits);
+-      if (handle->h_rsv_handle) {
+-              sub_reserved_credits(journal,
+-                                   handle->h_rsv_handle->h_buffer_credits);
+-      }
+-      if (atomic_dec_and_test(&transaction->t_updates))
+-              wake_up(&journal->j_wait_updates);
+-      tid = transaction->t_tid;
+-      spin_unlock(&transaction->t_handle_lock);
++      jbd_debug(2, "restarting handle %p\n", handle);
++      stop_this_handle(handle);
+       handle->h_transaction = NULL;
+-      current->journal_info = NULL;
+-      jbd_debug(2, "restarting handle %p\n", handle);
++      /*
++       * TODO: If we use READ_ONCE / WRITE_ONCE for j_commit_request we can
++       * get rid of pointless j_state_lock traffic like this.
++       */
++      read_lock(&journal->j_state_lock);
+       need_to_start = !tid_geq(journal->j_commit_request, tid);
+       read_unlock(&journal->j_state_lock);
+       if (need_to_start)
+               jbd2_log_start_commit(journal, tid);
+-
+-      rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
+       handle->h_buffer_credits = nblocks;
+-      /*
+-       * Restore the original nofs context because the journal restart
+-       * is basically the same thing as journal stop and start.
+-       * start_this_handle will start a new nofs context.
+-       */
+-      memalloc_nofs_restore(handle->saved_alloc_context);
+-      ret = start_this_handle(journal, handle, gfp_mask);
+-      return ret;
++      return start_this_handle(journal, handle, gfp_mask);
+ }
+ EXPORT_SYMBOL(jbd2__journal_restart);
+@@ -1734,16 +1743,12 @@ int jbd2_journal_stop(handle_t *handle)
+                * Handle is already detached from the transaction so there is
+                * nothing to do other than free the handle.
+                */
+-              if (handle->h_rsv_handle)
+-                      jbd2_free_handle(handle->h_rsv_handle);
++              memalloc_nofs_restore(handle->saved_alloc_context);
+               goto free_and_exit;
+       }
+       journal = transaction->t_journal;
+       tid = transaction->t_tid;
+-      J_ASSERT(journal_current_handle() == handle);
+-      J_ASSERT(atomic_read(&transaction->t_updates) > 0);
+-
+       if (is_handle_aborted(handle))
+               err = -EIO;
+@@ -1813,9 +1818,6 @@ int jbd2_journal_stop(handle_t *handle)
+       if (handle->h_sync)
+               transaction->t_synchronous_commit = 1;
+-      current->journal_info = NULL;
+-      atomic_sub(handle->h_buffer_credits,
+-                 &transaction->t_outstanding_credits);
+       /*
+        * If the handle is marked SYNC, we need to set another commit
+@@ -1845,27 +1847,19 @@ int jbd2_journal_stop(handle_t *handle)
+       }
+       /*
+-       * Once we drop t_updates, if it goes to zero the transaction
+-       * could start committing on us and eventually disappear.  So
+-       * once we do this, we must not dereference transaction
+-       * pointer again.
++       * Once stop_this_handle() drops t_updates, the transaction could start
++       * committing on us and eventually disappear.  So we must not
++       * dereference transaction pointer again after calling
++       * stop_this_handle().
+        */
+-      if (atomic_dec_and_test(&transaction->t_updates))
+-              wake_up(&journal->j_wait_updates);
+-
+-      rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
++      stop_this_handle(handle);
+       if (wait_for_commit)
+               err = jbd2_log_wait_commit(journal, tid);
+-      if (handle->h_rsv_handle)
+-              jbd2_journal_free_reserved(handle->h_rsv_handle);
+ free_and_exit:
+-      /*
+-       * Scope of the GFP_NOFS context is over here and so we can restore the
+-       * original alloc context.
+-       */
+-      memalloc_nofs_restore(handle->saved_alloc_context);
++      if (handle->h_rsv_handle)
++              jbd2_free_handle(handle->h_rsv_handle);
+       jbd2_free_handle(handle);
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch b/queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch
new file mode 100644 (file)
index 0000000..1f00af2
--- /dev/null
@@ -0,0 +1,104 @@
+From 526e6da0a66d8df0bb8243398f73b1ebf9279a78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2019 17:44:20 +0100
+Subject: jbd2: Reorganize jbd2_journal_stop()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit dfaf5ffda227be3e867fee7c0f6a66749392fbd0 ]
+
+Move code in jbd2_journal_stop() around a bit. It removes some
+unnecessary code duplication and will make factoring out parts common
+with jbd2__journal_restart() easier.
+
+Reviewed-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20191105164437.32602-14-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 40 ++++++++++++++++------------------------
+ 1 file changed, 16 insertions(+), 24 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 09f4d00fece2..ce66dbbf0f90 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1722,41 +1722,34 @@ int jbd2_journal_stop(handle_t *handle)
+       tid_t tid;
+       pid_t pid;
++      if (--handle->h_ref > 0) {
++              jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
++                                               handle->h_ref);
++              if (is_handle_aborted(handle))
++                      return -EIO;
++              return 0;
++      }
+       if (!transaction) {
+               /*
+-               * Handle is already detached from the transaction so
+-               * there is nothing to do other than decrease a refcount,
+-               * or free the handle if refcount drops to zero
++               * Handle is already detached from the transaction so there is
++               * nothing to do other than free the handle.
+                */
+-              if (--handle->h_ref > 0) {
+-                      jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
+-                                                       handle->h_ref);
+-                      return err;
+-              } else {
+-                      if (handle->h_rsv_handle)
+-                              jbd2_free_handle(handle->h_rsv_handle);
+-                      goto free_and_exit;
+-              }
++              if (handle->h_rsv_handle)
++                      jbd2_free_handle(handle->h_rsv_handle);
++              goto free_and_exit;
+       }
+       journal = transaction->t_journal;
++      tid = transaction->t_tid;
+       J_ASSERT(journal_current_handle() == handle);
++      J_ASSERT(atomic_read(&transaction->t_updates) > 0);
+       if (is_handle_aborted(handle))
+               err = -EIO;
+-      else
+-              J_ASSERT(atomic_read(&transaction->t_updates) > 0);
+-
+-      if (--handle->h_ref > 0) {
+-              jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
+-                        handle->h_ref);
+-              return err;
+-      }
+       jbd_debug(4, "Handle %p going down\n", handle);
+       trace_jbd2_handle_stats(journal->j_fs_dev->bd_dev,
+-                              transaction->t_tid,
+-                              handle->h_type, handle->h_line_no,
++                              tid, handle->h_type, handle->h_line_no,
+                               jiffies - handle->h_start_jiffies,
+                               handle->h_sync, handle->h_requested_credits,
+                               (handle->h_requested_credits -
+@@ -1841,7 +1834,7 @@ int jbd2_journal_stop(handle_t *handle)
+               jbd_debug(2, "transaction too old, requesting commit for "
+                                       "handle %p\n", handle);
+               /* This is non-blocking */
+-              jbd2_log_start_commit(journal, transaction->t_tid);
++              jbd2_log_start_commit(journal, tid);
+               /*
+                * Special case: JBD2_SYNC synchronous updates require us
+@@ -1857,7 +1850,6 @@ int jbd2_journal_stop(handle_t *handle)
+        * once we do this, we must not dereference transaction
+        * pointer again.
+        */
+-      tid = transaction->t_tid;
+       if (atomic_dec_and_test(&transaction->t_updates)) {
+               wake_up(&journal->j_wait_updates);
+               if (journal->j_barrier_count)
+-- 
+2.35.1
+
diff --git a/queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch b/queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch
new file mode 100644 (file)
index 0000000..3f05a41
--- /dev/null
@@ -0,0 +1,57 @@
+From c0ac030adcb47352b739d19e20d28b2fa3290a56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Aug 2021 08:54:19 +0200
+Subject: Revert "USB: bcma: Add a check for devm_gpiod_get"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit d91adc5322ab53df4b6d1989242bfb6c63163eb2 ]
+
+This reverts commit f3de5d857bb2362b00e2a8d4bc886cd49dcb66db.
+
+That commit broke USB on all routers that have USB always powered on and
+don't require toggling any GPIO. It's a majority of devices actually.
+
+The original code worked and seemed safe: vcc GPIO is optional and
+bcma_hci_platform_power_gpio() takes care of checking the pointer before
+using it.
+
+This revert fixes:
+[   10.801127] bcma_hcd: probe of bcma0:11 failed with error -2
+
+Fixes: f3de5d857bb2 ("USB: bcma: Add a check for devm_gpiod_get")
+Cc: stable <stable@vger.kernel.org>
+Cc: Chuhong Yuan <hslester96@gmail.com>
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20210831065419.18371-1-zajec5@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/bcma-hcd.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
+index 652fa29beb27..2400a826397a 100644
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -406,12 +406,9 @@ static int bcma_hcd_probe(struct bcma_device *core)
+               return -ENOMEM;
+       usb_dev->core = core;
+-      if (core->dev.of_node) {
++      if (core->dev.of_node)
+               usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+                                                   GPIOD_OUT_HIGH);
+-              if (IS_ERR(usb_dev->gpio_desc))
+-                      return PTR_ERR(usb_dev->gpio_desc);
+-      }
+       switch (core->id.id) {
+       case BCMA_CORE_USB20_HOST:
+-- 
+2.35.1
+
index abd835e83c6d1e5f7bbe6259a191b092fc4d9cc7..847a70ca117f07063c04347f42a119ba90c42cb7 100644 (file)
@@ -49,3 +49,17 @@ iio-light-apds9960-fix-wrong-register-for-gesture-gain.patch
 iio-core-fix-entry-not-deleted-when-iio_register_sw_trigger_type-fails.patch
 init-kconfig-fix-cc_has_asm_goto_tied_output-test-wi.patch
 nios2-add-force-for-vmlinuz.gz.patch
+iio-ms5611-simplify-io-callback-parameters.patch
+iio-pressure-ms5611-fixed-value-compensation-bug.patch
+ceph-do-not-update-snapshot-context-when-there-is-no.patch
+ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch
+usb-bcma-add-a-check-for-devm_gpiod_get.patch
+device.h-move-dev_printk-like-functions-to-dev_print.patch
+driver-core-add-device-probe-log-helper.patch
+revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch
+usb-bcma-make-gpio-explicitly-optional.patch
+firmware-google-release-devices-before-unregistering.patch
+firmware-coreboot-register-bus-in-module-init.patch
+jbd2-reorganize-jbd2_journal_stop.patch
+jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch
+jbd2-factor-out-common-parts-of-stopping-and-restart.patch
diff --git a/queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch b/queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch
new file mode 100644 (file)
index 0000000..1701c3a
--- /dev/null
@@ -0,0 +1,43 @@
+From b9ea1129368b877a7143b714b7e09b6820a28000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2019 16:35:32 +0800
+Subject: USB: bcma: Add a check for devm_gpiod_get
+
+From: Chuhong Yuan <hslester96@gmail.com>
+
+[ Upstream commit f3de5d857bb2362b00e2a8d4bc886cd49dcb66db ]
+
+bcma_hcd_probe misses a check for devm_gpiod_get and may miss
+the error.
+Add a check for it and return the error if a failure occurs.
+
+Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
+Link: https://lore.kernel.org/r/20191016083531.5734-1-hslester96@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/bcma-hcd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
+index 2400a826397a..652fa29beb27 100644
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -406,9 +406,12 @@ static int bcma_hcd_probe(struct bcma_device *core)
+               return -ENOMEM;
+       usb_dev->core = core;
+-      if (core->dev.of_node)
++      if (core->dev.of_node) {
+               usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+                                                   GPIOD_OUT_HIGH);
++              if (IS_ERR(usb_dev->gpio_desc))
++                      return PTR_ERR(usb_dev->gpio_desc);
++      }
+       switch (core->id.id) {
+       case BCMA_CORE_USB20_HOST:
+-- 
+2.35.1
+
diff --git a/queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch b/queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch
new file mode 100644 (file)
index 0000000..413af99
--- /dev/null
@@ -0,0 +1,71 @@
+From fc6503b10494eb9d7c522ee466f06a34e9868e76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Nov 2022 10:07:53 +0100
+Subject: USB: bcma: Make GPIO explicitly optional
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit cd136706b4f925aa5d316642543babac90d45910 ]
+
+What the code does is to not check the return value from
+devm_gpiod_get() and then avoid using an erroneous GPIO descriptor
+with IS_ERR_OR_NULL().
+
+This will miss real errors from the GPIO core that should not be
+ignored, such as probe deferral.
+
+Instead request the GPIO as explicitly optional, which means that
+if it doesn't exist, the descriptor returned will be NULL.
+
+Then we can add error handling and also avoid just doing this on
+the device tree path, and simplify the site where the optional
+GPIO descriptor is used.
+
+There were some problems with cleaning up this GPIO descriptor
+use in the past, but this is the proper way to deal with it.
+
+Cc: Rafał Miłecki <rafal@milecki.pl>
+Cc: Chuhong Yuan <hslester96@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: stable <stable@kernel.org>
+Link: https://lore.kernel.org/r/20221107090753.1404679-1-linus.walleij@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/bcma-hcd.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
+index 2400a826397a..d8f2af8fb89d 100644
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -285,7 +285,7 @@ static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+ {
+       struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+-      if (IS_ERR_OR_NULL(usb_dev->gpio_desc))
++      if (!usb_dev->gpio_desc)
+               return;
+       gpiod_set_value(usb_dev->gpio_desc, val);
+@@ -406,9 +406,11 @@ static int bcma_hcd_probe(struct bcma_device *core)
+               return -ENOMEM;
+       usb_dev->core = core;
+-      if (core->dev.of_node)
+-              usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+-                                                  GPIOD_OUT_HIGH);
++      usb_dev->gpio_desc = devm_gpiod_get_optional(&core->dev, "vcc",
++                                                   GPIOD_OUT_HIGH);
++      if (IS_ERR(usb_dev->gpio_desc))
++              return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc),
++                                   "error obtaining VCC GPIO");
+       switch (core->id.id) {
+       case BCMA_CORE_USB20_HOST:
+-- 
+2.35.1
+