--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+