Merge tag 'driver-core-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Feb 2023 20:58:55 +0000 (12:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Feb 2023 20:58:55 +0000 (12:58 -0800)
Pull driver core updates from Greg KH:
 "Here is the large set of driver core changes for 6.3-rc1.

  There's a lot of changes this development cycle, most of the work
  falls into two different categories:

   - fw_devlink fixes and updates. This has gone through numerous review
     cycles and lots of review and testing by lots of different devices.
     Hopefully all should be good now, and Saravana will be keeping a
     watch for any potential regression on odd embedded systems.

   - driver core changes to work to make struct bus_type able to be
     moved into read-only memory (i.e. const) The recent work with Rust
     has pointed out a number of areas in the driver core where we are
     passing around and working with structures that really do not have
     to be dynamic at all, and they should be able to be read-only
     making things safer overall. This is the contuation of that work
     (started last release with kobject changes) in moving struct
     bus_type to be constant. We didn't quite make it for this release,
     but the remaining patches will be finished up for the release after
     this one, but the groundwork has been laid for this effort.

  Other than that we have in here:

   - debugfs memory leak fixes in some subsystems

   - error path cleanups and fixes for some never-able-to-be-hit
     codepaths.

   - cacheinfo rework and fixes

   - Other tiny fixes, full details are in the shortlog

  All of these have been in linux-next for a while with no reported
  problems"

[ Geert Uytterhoeven points out that that last sentence isn't true, and
  that there's a pending report that has a fix that is queued up - Linus ]

* tag 'driver-core-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (124 commits)
  debugfs: drop inline constant formatting for ERR_PTR(-ERROR)
  OPP: fix error checking in opp_migrate_dentry()
  debugfs: update comment of debugfs_rename()
  i3c: fix device.h kernel-doc warnings
  dma-mapping: no need to pass a bus_type into get_arch_dma_ops()
  driver core: class: move EXPORT_SYMBOL_GPL() lines to the correct place
  Revert "driver core: add error handling for devtmpfs_create_node()"
  Revert "devtmpfs: add debug info to handle()"
  Revert "devtmpfs: remove return value of devtmpfs_delete_node()"
  driver core: cpu: don't hand-override the uevent bus_type callback.
  devtmpfs: remove return value of devtmpfs_delete_node()
  devtmpfs: add debug info to handle()
  driver core: add error handling for devtmpfs_create_node()
  driver core: bus: update my copyright notice
  driver core: bus: add bus_get_dev_root() function
  driver core: bus: constify bus_unregister()
  driver core: bus: constify some internal functions
  driver core: bus: constify bus_get_kset()
  driver core: bus: constify bus_register/unregister_notifier()
  driver core: remove private pointer from struct bus_type
  ...

42 files changed:
1  2 
block/genhd.c
drivers/acpi/device_sysfs.c
drivers/base/core.c
drivers/base/devtmpfs.c
drivers/bus/mhi/ep/main.c
drivers/bus/mhi/host/init.c
drivers/bus/sunxi-rsb.c
drivers/fpga/dfl.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/drm_mipi_dsi.c
drivers/hid/hid-core.c
drivers/hv/vmbus_drv.c
drivers/i2c/i2c-core-base.c
drivers/misc/mei/bus.c
drivers/mmc/core/sdio_bus.c
drivers/net/phy/mdio_bus.c
drivers/nvdimm/nd.h
drivers/of/device.c
drivers/of/property.c
drivers/platform/surface/aggregator/bus.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/scsi/scsi_sysfs.c
drivers/spi/spi.c
drivers/thunderbolt/switch.c
drivers/thunderbolt/tb.h
drivers/usb/common/ulpi.c
drivers/usb/core/usb.c
drivers/usb/typec/bus.c
drivers/usb/typec/class.c
drivers/xen/pvcalls-back.c
fs/debugfs/inode.c
fs/dlm/lockspace.c
fs/gfs2/sys.c
fs/kernfs/dir.c
include/drm/drm_mipi_dsi.h
include/linux/acpi.h
include/linux/firewire.h
include/linux/hyperv.h
include/linux/spi/spi.h
include/linux/surface_aggregator/device.h
include/sound/hdaudio.h

diff --combined block/genhd.c
index 093ef292e98f7f913e96878065485cb182f7250b,09f2ac548832aad9f2c82d4975719fd0532249be..d09d775c222a94c36c89fcba4426c0989b2183e7
@@@ -1016,8 -1016,9 +1016,8 @@@ ssize_t part_inflight_show(struct devic
  static ssize_t disk_capability_show(struct device *dev,
                                    struct device_attribute *attr, char *buf)
  {
 -      struct gendisk *disk = dev_to_disk(dev);
 -
 -      return sprintf(buf, "%x\n", disk->flags);
 +      dev_warn_once(dev, "the capability attribute has been deprecated.\n");
 +      return sprintf(buf, "0\n");
  }
  
  static ssize_t disk_alignment_offset_show(struct device *dev,
@@@ -1200,7 -1201,7 +1200,7 @@@ struct class block_class = 
        .dev_uevent     = block_uevent,
  };
  
- static char *block_devnode(struct device *dev, umode_t *mode,
+ static char *block_devnode(const struct device *dev, umode_t *mode,
                           kuid_t *uid, kgid_t *gid)
  {
        struct gendisk *disk = dev_to_disk(dev);
index c3aa15571f164ef8dc8cfe120cd2294a28890726,daff2c0c5c523ebdf759d63b92306f9846f03eed..0fbfbaa8d8e3d223f793a2d974430a43189c7830
@@@ -78,7 -78,7 +78,7 @@@ static void acpi_data_node_release(stru
        complete(&dn->kobj_done);
  }
  
 -static struct kobj_type acpi_data_node_ktype = {
 +static const struct kobj_type acpi_data_node_ktype = {
        .sysfs_ops = &acpi_data_node_sysfs_ops,
        .default_groups = acpi_data_node_default_groups,
        .release = acpi_data_node_release,
@@@ -133,7 -133,7 +133,7 @@@ static void acpi_hide_nondev_subnodes(s
   *         -EINVAL: output error
   *         -ENOMEM: output is truncated
   */
- static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
+ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalias,
                               int size)
  {
        int len;
   * only be called for devices having ACPI_DT_NAMESPACE_HID in their list of
   * ACPI/PNP IDs.
   */
- static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
+ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias,
                              int size)
  {
        struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
        return len;
  }
  
- int __acpi_device_uevent_modalias(struct acpi_device *adev,
+ int __acpi_device_uevent_modalias(const struct acpi_device *adev,
                                  struct kobj_uevent_env *env)
  {
        int len;
   * Because other buses do not support ACPI HIDs & CIDs, e.g. for a device with
   * hid:IBM0001 and cid:ACPI0001 you get: "acpi:IBM0001:ACPI0001".
   */
- int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+ int acpi_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
  {
        return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
  }
diff --combined drivers/base/core.c
index bb36aca8d1b7ae93f83a4ea60d1123b68fa23894,f9297c68214ae47db140860222f4bcf5e709d85f..e54a10b5dbd713d1ea1f29f4634f1af4be284b27
@@@ -54,11 -54,12 +54,12 @@@ static LIST_HEAD(deferred_sync)
  static unsigned int defer_sync_state_count = 1;
  static DEFINE_MUTEX(fwnode_link_lock);
  static bool fw_devlink_is_permissive(void);
+ static void __fw_devlink_link_to_consumers(struct device *dev);
  static bool fw_devlink_drv_reg_done;
  static bool fw_devlink_best_effort;
  
  /**
-  * fwnode_link_add - Create a link between two fwnode_handles.
+  * __fwnode_link_add - Create a link between two fwnode_handles.
   * @con: Consumer end of the link.
   * @sup: Supplier end of the link.
   *
   * Attempts to create duplicate links between the same pair of fwnode handles
   * are ignored and there is no reference counting.
   */
- int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
+ static int __fwnode_link_add(struct fwnode_handle *con,
+                            struct fwnode_handle *sup, u8 flags)
  {
        struct fwnode_link *link;
-       int ret = 0;
-       mutex_lock(&fwnode_link_lock);
  
        list_for_each_entry(link, &sup->consumers, s_hook)
-               if (link->consumer == con)
-                       goto out;
+               if (link->consumer == con) {
+                       link->flags |= flags;
+                       return 0;
+               }
  
        link = kzalloc(sizeof(*link), GFP_KERNEL);
-       if (!link) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!link)
+               return -ENOMEM;
  
        link->supplier = sup;
        INIT_LIST_HEAD(&link->s_hook);
        link->consumer = con;
        INIT_LIST_HEAD(&link->c_hook);
+       link->flags = flags;
  
        list_add(&link->s_hook, &sup->consumers);
        list_add(&link->c_hook, &con->suppliers);
        pr_debug("%pfwP Linked as a fwnode consumer to %pfwP\n",
                 con, sup);
- out:
-       mutex_unlock(&fwnode_link_lock);
  
+       return 0;
+ }
+ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
+ {
+       int ret;
+       mutex_lock(&fwnode_link_lock);
+       ret = __fwnode_link_add(con, sup, 0);
+       mutex_unlock(&fwnode_link_lock);
        return ret;
  }
  
@@@ -121,6 -129,19 +129,19 @@@ static void __fwnode_link_del(struct fw
        kfree(link);
  }
  
+ /**
+  * __fwnode_link_cycle - Mark a fwnode link as being part of a cycle.
+  * @link: the fwnode_link to be marked
+  *
+  * The fwnode_link_lock needs to be held when this function is called.
+  */
+ static void __fwnode_link_cycle(struct fwnode_link *link)
+ {
+       pr_debug("%pfwf: Relaxing link with %pfwf\n",
+                link->consumer, link->supplier);
+       link->flags |= FWLINK_FLAG_CYCLE;
+ }
  /**
   * fwnode_links_purge_suppliers - Delete all supplier links of fwnode_handle.
   * @fwnode: fwnode whose supplier links need to be deleted
@@@ -181,6 -202,52 +202,51 @@@ void fw_devlink_purge_absent_suppliers(
  }
  EXPORT_SYMBOL_GPL(fw_devlink_purge_absent_suppliers);
  
 -#ifdef CONFIG_SRCU
+ /**
+  * __fwnode_links_move_consumers - Move consumer from @from to @to fwnode_handle
+  * @from: move consumers away from this fwnode
+  * @to: move consumers to this fwnode
+  *
+  * Move all consumer links from @from fwnode to @to fwnode.
+  */
+ static void __fwnode_links_move_consumers(struct fwnode_handle *from,
+                                         struct fwnode_handle *to)
+ {
+       struct fwnode_link *link, *tmp;
+       list_for_each_entry_safe(link, tmp, &from->consumers, s_hook) {
+               __fwnode_link_add(link->consumer, to, link->flags);
+               __fwnode_link_del(link);
+       }
+ }
+ /**
+  * __fw_devlink_pickup_dangling_consumers - Pick up dangling consumers
+  * @fwnode: fwnode from which to pick up dangling consumers
+  * @new_sup: fwnode of new supplier
+  *
+  * If the @fwnode has a corresponding struct device and the device supports
+  * probing (that is, added to a bus), then we want to let fw_devlink create
+  * MANAGED device links to this device, so leave @fwnode and its descendant's
+  * fwnode links alone.
+  *
+  * Otherwise, move its consumers to the new supplier @new_sup.
+  */
+ static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode,
+                                                  struct fwnode_handle *new_sup)
+ {
+       struct fwnode_handle *child;
+       if (fwnode->dev && fwnode->dev->bus)
+               return;
+       fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
+       __fwnode_links_move_consumers(fwnode, new_sup);
+       fwnode_for_each_available_child_node(fwnode, child)
+               __fw_devlink_pickup_dangling_consumers(child, new_sup);
+ }
  static DEFINE_MUTEX(device_links_lock);
  DEFINE_STATIC_SRCU(device_links_srcu);
  
@@@ -219,6 -286,47 +285,6 @@@ static void device_link_remove_from_lis
        list_del_rcu(&link->s_node);
        list_del_rcu(&link->c_node);
  }
 -#else /* !CONFIG_SRCU */
 -static DECLARE_RWSEM(device_links_lock);
 -
 -static inline void device_links_write_lock(void)
 -{
 -      down_write(&device_links_lock);
 -}
 -
 -static inline void device_links_write_unlock(void)
 -{
 -      up_write(&device_links_lock);
 -}
 -
 -int device_links_read_lock(void)
 -{
 -      down_read(&device_links_lock);
 -      return 0;
 -}
 -
 -void device_links_read_unlock(int not_used)
 -{
 -      up_read(&device_links_lock);
 -}
 -
 -#ifdef CONFIG_DEBUG_LOCK_ALLOC
 -int device_links_read_lock_held(void)
 -{
 -      return lockdep_is_held(&device_links_lock);
 -}
 -#endif
 -
 -static inline void device_link_synchronize_removal(void)
 -{
 -}
 -
 -static void device_link_remove_from_lists(struct device_link *link)
 -{
 -      list_del(&link->s_node);
 -      list_del(&link->c_node);
 -}
 -#endif /* !CONFIG_SRCU */
  
  static bool device_is_ancestor(struct device *dev, struct device *target)
  {
        return false;
  }
  
+ static inline bool device_link_flag_is_sync_state_only(u32 flags)
+ {
+       return (flags & ~(DL_FLAG_INFERRED | DL_FLAG_CYCLE)) ==
+               (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED);
+ }
  /**
   * device_is_dependent - Check if one device depends on another one
   * @dev: Device to check dependencies for.
@@@ -256,8 -370,7 +328,7 @@@ int device_is_dependent(struct device *
                return ret;
  
        list_for_each_entry(link, &dev->links.consumers, s_node) {
-               if ((link->flags & ~DL_FLAG_INFERRED) ==
-                   (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED))
+               if (device_link_flag_is_sync_state_only(link->flags))
                        continue;
  
                if (link->consumer == target)
@@@ -330,8 -443,7 +401,7 @@@ static int device_reorder_to_tail(struc
  
        device_for_each_child(dev, NULL, device_reorder_to_tail);
        list_for_each_entry(link, &dev->links.consumers, s_node) {
-               if ((link->flags & ~DL_FLAG_INFERRED) ==
-                   (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED))
+               if (device_link_flag_is_sync_state_only(link->flags))
                        continue;
                device_reorder_to_tail(link->consumer, NULL);
        }
@@@ -592,7 -704,8 +662,8 @@@ postcore_initcall(devlink_class_init)
                               DL_FLAG_AUTOREMOVE_SUPPLIER | \
                               DL_FLAG_AUTOPROBE_CONSUMER  | \
                               DL_FLAG_SYNC_STATE_ONLY | \
-                              DL_FLAG_INFERRED)
+                              DL_FLAG_INFERRED | \
+                              DL_FLAG_CYCLE)
  
  #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \
                            DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE)
@@@ -661,8 -774,6 +732,6 @@@ struct device_link *device_link_add(str
        if (!consumer || !supplier || consumer == supplier ||
            flags & ~DL_ADD_VALID_FLAGS ||
            (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) ||
-           (flags & DL_FLAG_SYNC_STATE_ONLY &&
-            (flags & ~DL_FLAG_INFERRED) != DL_FLAG_SYNC_STATE_ONLY) ||
            (flags & DL_FLAG_AUTOPROBE_CONSUMER &&
             flags & (DL_FLAG_AUTOREMOVE_CONSUMER |
                      DL_FLAG_AUTOREMOVE_SUPPLIER)))
        if (!(flags & DL_FLAG_STATELESS))
                flags |= DL_FLAG_MANAGED;
  
+       if (flags & DL_FLAG_SYNC_STATE_ONLY &&
+           !device_link_flag_is_sync_state_only(flags))
+               return NULL;
        device_links_write_lock();
        device_pm_lock();
  
@@@ -942,6 -1057,21 +1015,21 @@@ static bool dev_is_best_effort(struct d
                (dev->fwnode && (dev->fwnode->flags & FWNODE_FLAG_BEST_EFFORT));
  }
  
+ static struct fwnode_handle *fwnode_links_check_suppliers(
+                                               struct fwnode_handle *fwnode)
+ {
+       struct fwnode_link *link;
+       if (!fwnode || fw_devlink_is_permissive())
+               return NULL;
+       list_for_each_entry(link, &fwnode->suppliers, c_hook)
+               if (!(link->flags & FWLINK_FLAG_CYCLE))
+                       return link->supplier;
+       return NULL;
+ }
  /**
   * device_links_check_suppliers - Check presence of supplier drivers.
   * @dev: Consumer device.
@@@ -969,11 -1099,8 +1057,8 @@@ int device_links_check_suppliers(struc
         * probe.
         */
        mutex_lock(&fwnode_link_lock);
-       if (dev->fwnode && !list_empty(&dev->fwnode->suppliers) &&
-           !fw_devlink_is_permissive()) {
-               sup_fw = list_first_entry(&dev->fwnode->suppliers,
-                                         struct fwnode_link,
-                                         c_hook)->supplier;
+       sup_fw = fwnode_links_check_suppliers(dev->fwnode);
+       if (sup_fw) {
                if (!dev_is_best_effort(dev)) {
                        fwnode_ret = -EPROBE_DEFER;
                        dev_err_probe(dev, -EPROBE_DEFER,
@@@ -1162,7 -1289,9 +1247,9 @@@ static ssize_t waiting_for_supplier_sho
        bool val;
  
        device_lock(dev);
-       val = !list_empty(&dev->fwnode->suppliers);
+       mutex_lock(&fwnode_link_lock);
+       val = !!fwnode_links_check_suppliers(dev->fwnode);
+       mutex_unlock(&fwnode_link_lock);
        device_unlock(dev);
        return sysfs_emit(buf, "%u\n", val);
  }
@@@ -1225,16 -1354,23 +1312,23 @@@ void device_links_driver_bound(struct d
         * them. So, fw_devlink no longer needs to create device links to any
         * of the device's suppliers.
         *
-        * Also, if a child firmware node of this bound device is not added as
-        * a device by now, assume it is never going to be added and make sure
-        * other devices don't defer probe indefinitely by waiting for such a
-        * child device.
+        * Also, if a child firmware node of this bound device is not added as a
+        * device by now, assume it is never going to be added. Make this bound
+        * device the fallback supplier to the dangling consumers of the child
+        * firmware node because this bound device is probably implementing the
+        * child firmware node functionality and we don't want the dangling
+        * consumers to defer probe indefinitely waiting for a device for the
+        * child firmware node.
         */
        if (dev->fwnode && dev->fwnode->dev == dev) {
                struct fwnode_handle *child;
                fwnode_links_purge_suppliers(dev->fwnode);
+               mutex_lock(&fwnode_link_lock);
                fwnode_for_each_available_child_node(dev->fwnode, child)
-                       fw_devlink_purge_absent_suppliers(child);
+                       __fw_devlink_pickup_dangling_consumers(child,
+                                                              dev->fwnode);
+               __fw_devlink_link_to_consumers(dev);
+               mutex_unlock(&fwnode_link_lock);
        }
        device_remove_file(dev, &dev_attr_waiting_for_supplier);
  
@@@ -1591,8 -1727,11 +1685,11 @@@ static int __init fw_devlink_strict_set
  }
  early_param("fw_devlink.strict", fw_devlink_strict_setup);
  
u32 fw_devlink_get_flags(void)
static inline u32 fw_devlink_get_flags(u8 fwlink_flags)
  {
+       if (fwlink_flags & FWLINK_FLAG_CYCLE)
+               return FW_DEVLINK_FLAGS_PERMISSIVE | DL_FLAG_CYCLE;
        return fw_devlink_flags;
  }
  
@@@ -1630,7 -1769,7 +1727,7 @@@ static void fw_devlink_relax_link(struc
        if (!(link->flags & DL_FLAG_INFERRED))
                return;
  
-       if (link->flags == (DL_FLAG_MANAGED | FW_DEVLINK_FLAGS_PERMISSIVE))
+       if (device_link_flag_is_sync_state_only(link->flags))
                return;
  
        pm_runtime_drop_link(link);
@@@ -1727,44 -1866,138 +1824,138 @@@ static void fw_devlink_unblock_consumer
        device_links_write_unlock();
  }
  
+ static bool fwnode_init_without_drv(struct fwnode_handle *fwnode)
+ {
+       struct device *dev;
+       bool ret;
+       if (!(fwnode->flags & FWNODE_FLAG_INITIALIZED))
+               return false;
+       dev = get_dev_from_fwnode(fwnode);
+       ret = !dev || dev->links.status == DL_DEV_NO_DRIVER;
+       put_device(dev);
+       return ret;
+ }
+ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode)
+ {
+       struct fwnode_handle *parent;
+       fwnode_for_each_parent_node(fwnode, parent) {
+               if (fwnode_init_without_drv(parent)) {
+                       fwnode_handle_put(parent);
+                       return true;
+               }
+       }
+       return false;
+ }
  /**
-  * fw_devlink_relax_cycle - Convert cyclic links to SYNC_STATE_ONLY links
-  * @con: Device to check dependencies for.
-  * @sup: Device to check against.
-  *
-  * Check if @sup depends on @con or any device dependent on it (its child or
-  * its consumer etc).  When such a cyclic dependency is found, convert all
-  * device links created solely by fw_devlink into SYNC_STATE_ONLY device links.
-  * This is the equivalent of doing fw_devlink=permissive just between the
-  * devices in the cycle. We need to do this because, at this point, fw_devlink
-  * can't tell which of these dependencies is not a real dependency.
-  *
-  * Return 1 if a cycle is found. Otherwise, return 0.
+  * __fw_devlink_relax_cycles - Relax and mark dependency cycles.
+  * @con: Potential consumer device.
+  * @sup_handle: Potential supplier's fwnode.
+  *
+  * Needs to be called with fwnode_lock and device link lock held.
+  *
+  * Check if @sup_handle or any of its ancestors or suppliers direct/indirectly
+  * depend on @con. This function can detect multiple cyles between @sup_handle
+  * and @con. When such dependency cycles are found, convert all device links
+  * created solely by fw_devlink into SYNC_STATE_ONLY device links. Also, mark
+  * all fwnode links in the cycle with FWLINK_FLAG_CYCLE so that when they are
+  * converted into a device link in the future, they are created as
+  * SYNC_STATE_ONLY device links. This is the equivalent of doing
+  * fw_devlink=permissive just between the devices in the cycle. We need to do
+  * this because, at this point, fw_devlink can't tell which of these
+  * dependencies is not a real dependency.
+  *
+  * Return true if one or more cycles were found. Otherwise, return false.
   */
- static int fw_devlink_relax_cycle(struct device *con, void *sup)
+ static bool __fw_devlink_relax_cycles(struct device *con,
+                                struct fwnode_handle *sup_handle)
  {
-       struct device_link *link;
-       int ret;
+       struct device *sup_dev = NULL, *par_dev = NULL;
+       struct fwnode_link *link;
+       struct device_link *dev_link;
+       bool ret = false;
  
-       if (con == sup)
-               return 1;
+       if (!sup_handle)
+               return false;
  
-       ret = device_for_each_child(con, sup, fw_devlink_relax_cycle);
-       if (ret)
-               return ret;
+       /*
+        * We aren't trying to find all cycles. Just a cycle between con and
+        * sup_handle.
+        */
+       if (sup_handle->flags & FWNODE_FLAG_VISITED)
+               return false;
  
-       list_for_each_entry(link, &con->links.consumers, s_node) {
-               if ((link->flags & ~DL_FLAG_INFERRED) ==
-                   (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED))
-                       continue;
+       sup_handle->flags |= FWNODE_FLAG_VISITED;
  
-               if (!fw_devlink_relax_cycle(link->consumer, sup))
-                       continue;
+       sup_dev = get_dev_from_fwnode(sup_handle);
  
-               ret = 1;
+       /* Termination condition. */
+       if (sup_dev == con) {
+               ret = true;
+               goto out;
+       }
  
-               fw_devlink_relax_link(link);
+       /*
+        * If sup_dev is bound to a driver and @con hasn't started binding to a
+        * driver, sup_dev can't be a consumer of @con. So, no need to check
+        * further.
+        */
+       if (sup_dev && sup_dev->links.status ==  DL_DEV_DRIVER_BOUND &&
+           con->links.status == DL_DEV_NO_DRIVER) {
+               ret = false;
+               goto out;
+       }
+       list_for_each_entry(link, &sup_handle->suppliers, c_hook) {
+               if (__fw_devlink_relax_cycles(con, link->supplier)) {
+                       __fwnode_link_cycle(link);
+                       ret = true;
+               }
        }
+       /*
+        * Give priority to device parent over fwnode parent to account for any
+        * quirks in how fwnodes are converted to devices.
+        */
+       if (sup_dev)
+               par_dev = get_device(sup_dev->parent);
+       else
+               par_dev = fwnode_get_next_parent_dev(sup_handle);
+       if (par_dev && __fw_devlink_relax_cycles(con, par_dev->fwnode))
+               ret = true;
+       if (!sup_dev)
+               goto out;
+       list_for_each_entry(dev_link, &sup_dev->links.suppliers, c_node) {
+               /*
+                * Ignore a SYNC_STATE_ONLY flag only if it wasn't marked as
+                * such due to a cycle.
+                */
+               if (device_link_flag_is_sync_state_only(dev_link->flags) &&
+                   !(dev_link->flags & DL_FLAG_CYCLE))
+                       continue;
+               if (__fw_devlink_relax_cycles(con,
+                                             dev_link->supplier->fwnode)) {
+                       fw_devlink_relax_link(dev_link);
+                       dev_link->flags |= DL_FLAG_CYCLE;
+                       ret = true;
+               }
+       }
+ out:
+       sup_handle->flags &= ~FWNODE_FLAG_VISITED;
+       put_device(sup_dev);
+       put_device(par_dev);
        return ret;
  }
  
   * fw_devlink_create_devlink - Create a device link from a consumer to fwnode
   * @con: consumer device for the device link
   * @sup_handle: fwnode handle of supplier
-  * @flags: devlink flags
+  * @link: fwnode link that's being converted to a device link
   *
   * This function will try to create a device link between the consumer device
   * @con and the supplier device represented by @sup_handle.
   *  possible to do that in the future
   */
  static int fw_devlink_create_devlink(struct device *con,
-                                    struct fwnode_handle *sup_handle, u32 flags)
+                                    struct fwnode_handle *sup_handle,
+                                    struct fwnode_link *link)
  {
        struct device *sup_dev;
        int ret = 0;
+       u32 flags;
+       if (con->fwnode == link->consumer)
+               flags = fw_devlink_get_flags(link->flags);
+       else
+               flags = FW_DEVLINK_FLAGS_PERMISSIVE;
  
        /*
         * In some cases, a device P might also be a supplier to its child node
            fwnode_is_ancestor_of(sup_handle, con->fwnode))
                return -EINVAL;
  
-       sup_dev = get_dev_from_fwnode(sup_handle);
+       /*
+        * SYNC_STATE_ONLY device links don't block probing and supports cycles.
+        * So cycle detection isn't necessary and shouldn't be done.
+        */
+       if (!(flags & DL_FLAG_SYNC_STATE_ONLY)) {
+               device_links_write_lock();
+               if (__fw_devlink_relax_cycles(con, sup_handle)) {
+                       __fwnode_link_cycle(link);
+                       flags = fw_devlink_get_flags(link->flags);
+                       dev_info(con, "Fixed dependency cycle(s) with %pfwf\n",
+                                sup_handle);
+               }
+               device_links_write_unlock();
+       }
+       if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE)
+               sup_dev = fwnode_get_next_parent_dev(sup_handle);
+       else
+               sup_dev = get_dev_from_fwnode(sup_handle);
        if (sup_dev) {
                /*
                 * If it's one of those drivers that don't actually bind to
                 */
                if (sup_dev->links.status == DL_DEV_NO_DRIVER &&
                    sup_handle->flags & FWNODE_FLAG_INITIALIZED) {
+                       dev_dbg(con,
+                               "Not linking %pfwf - dev might never probe\n",
+                               sup_handle);
                        ret = -EINVAL;
                        goto out;
                }
  
-               /*
-                * If this fails, it is due to cycles in device links.  Just
-                * give up on this link and treat it as invalid.
-                */
-               if (!device_link_add(con, sup_dev, flags) &&
-                   !(flags & DL_FLAG_SYNC_STATE_ONLY)) {
-                       dev_info(con, "Fixing up cyclic dependency with %s\n",
-                                dev_name(sup_dev));
-                       device_links_write_lock();
-                       fw_devlink_relax_cycle(con, sup_dev);
-                       device_links_write_unlock();
-                       device_link_add(con, sup_dev,
-                                       FW_DEVLINK_FLAGS_PERMISSIVE);
+               if (!device_link_add(con, sup_dev, flags)) {
+                       dev_err(con, "Failed to create device link with %s\n",
+                               dev_name(sup_dev));
                        ret = -EINVAL;
                }
  
                goto out;
        }
  
-       /* Supplier that's already initialized without a struct device. */
-       if (sup_handle->flags & FWNODE_FLAG_INITIALIZED)
-               return -EINVAL;
-       /*
-        * DL_FLAG_SYNC_STATE_ONLY doesn't block probing and supports
-        * cycles. So cycle detection isn't necessary and shouldn't be
-        * done.
-        */
-       if (flags & DL_FLAG_SYNC_STATE_ONLY)
-               return -EAGAIN;
        /*
-        * If we can't find the supplier device from its fwnode, it might be
-        * due to a cyclic dependency between fwnodes. Some of these cycles can
-        * be broken by applying logic. Check for these types of cycles and
-        * break them so that devices in the cycle probe properly.
-        *
-        * If the supplier's parent is dependent on the consumer, then the
-        * consumer and supplier have a cyclic dependency. Since fw_devlink
-        * can't tell which of the inferred dependencies are incorrect, don't
-        * enforce probe ordering between any of the devices in this cyclic
-        * dependency. Do this by relaxing all the fw_devlink device links in
-        * this cycle and by treating the fwnode link between the consumer and
-        * the supplier as an invalid dependency.
+        * Supplier or supplier's ancestor already initialized without a struct
+        * device or being probed by a driver.
         */
-       sup_dev = fwnode_get_next_parent_dev(sup_handle);
-       if (sup_dev && device_is_dependent(con, sup_dev)) {
-               dev_info(con, "Fixing up cyclic dependency with %pfwP (%s)\n",
-                        sup_handle, dev_name(sup_dev));
-               device_links_write_lock();
-               fw_devlink_relax_cycle(con, sup_dev);
-               device_links_write_unlock();
-               ret = -EINVAL;
-       } else {
-               /*
-                * Can't check for cycles or no cycles. So let's try
-                * again later.
-                */
-               ret = -EAGAIN;
+       if (fwnode_init_without_drv(sup_handle) ||
+           fwnode_ancestor_init_without_drv(sup_handle)) {
+               dev_dbg(con, "Not linking %pfwf - might never become dev\n",
+                       sup_handle);
+               return -EINVAL;
        }
  
+       ret = -EAGAIN;
  out:
        put_device(sup_dev);
        return ret;
@@@ -1914,7 -2136,6 +2094,6 @@@ static void __fw_devlink_link_to_consum
        struct fwnode_link *link, *tmp;
  
        list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook) {
-               u32 dl_flags = fw_devlink_get_flags();
                struct device *con_dev;
                bool own_link = true;
                int ret;
                                con_dev = NULL;
                        } else {
                                own_link = false;
-                               dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
                        }
                }
  
                if (!con_dev)
                        continue;
  
-               ret = fw_devlink_create_devlink(con_dev, fwnode, dl_flags);
+               ret = fw_devlink_create_devlink(con_dev, fwnode, link);
                put_device(con_dev);
                if (!own_link || ret == -EAGAIN)
                        continue;
   *
   * The function creates normal (non-SYNC_STATE_ONLY) device links between @dev
   * and the real suppliers of @dev. Once these device links are created, the
-  * fwnode links are deleted. When such device links are successfully created,
-  * this function is called recursively on those supplier devices. This is
-  * needed to detect and break some invalid cycles in fwnode links.  See
-  * fw_devlink_create_devlink() for more details.
+  * fwnode links are deleted.
   *
   * In addition, it also looks at all the suppliers of the entire fwnode tree
   * because some of the child devices of @dev that have not been added yet
@@@ -1992,44 -2209,16 +2167,16 @@@ static void __fw_devlink_link_to_suppli
        bool own_link = (dev->fwnode == fwnode);
        struct fwnode_link *link, *tmp;
        struct fwnode_handle *child = NULL;
-       u32 dl_flags;
-       if (own_link)
-               dl_flags = fw_devlink_get_flags();
-       else
-               dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
  
        list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) {
                int ret;
-               struct device *sup_dev;
                struct fwnode_handle *sup = link->supplier;
  
-               ret = fw_devlink_create_devlink(dev, sup, dl_flags);
+               ret = fw_devlink_create_devlink(dev, sup, link);
                if (!own_link || ret == -EAGAIN)
                        continue;
  
                __fwnode_link_del(link);
-               /* If no device link was created, nothing more to do. */
-               if (ret)
-                       continue;
-               /*
-                * If a device link was successfully created to a supplier, we
-                * now need to try and link the supplier to all its suppliers.
-                *
-                * This is needed to detect and delete false dependencies in
-                * fwnode links that haven't been converted to a device link
-                * yet. See comments in fw_devlink_create_devlink() for more
-                * details on the false dependency.
-                *
-                * Without deleting these false dependencies, some devices will
-                * never probe because they'll keep waiting for their false
-                * dependency fwnode links to be converted to device links.
-                */
-               sup_dev = get_dev_from_fwnode(sup);
-               __fw_devlink_link_to_suppliers(sup_dev, sup_dev->fwnode);
-               put_device(sup_dev);
        }
  
        /*
@@@ -2312,7 -2501,7 +2459,7 @@@ static void device_get_ownership(const 
                dev->class->get_ownership(dev, uid, gid);
  }
  
- static struct kobj_type device_ktype = {
+ static const struct kobj_type device_ktype = {
        .release        = device_release,
        .sysfs_ops      = &dev_sysfs_ops,
        .namespace      = device_namespace,
@@@ -2345,9 -2534,9 +2492,9 @@@ static const char *dev_uevent_name(cons
        return NULL;
  }
  
- static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
+ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
  {
-       struct device *dev = kobj_to_dev(kobj);
+       const struct device *dev = kobj_to_dev(kobj);
        int retval = 0;
  
        /* add device node properties if present */
@@@ -2950,7 -3139,7 +3097,7 @@@ struct kobj_ns_type_operations *class_d
        return dir->class->ns_type;
  }
  
- static struct kobj_type class_dir_ktype = {
+ static const struct kobj_type class_dir_ktype = {
        .release        = class_dir_release,
        .sysfs_ops      = &kobj_sysfs_ops,
        .child_ns_type  = class_dir_child_ns_type
@@@ -2984,8 -3173,9 +3131,9 @@@ static DEFINE_MUTEX(gdp_mutex)
  static struct kobject *get_device_parent(struct device *dev,
                                         struct device *parent)
  {
+       struct kobject *kobj = NULL;
        if (dev->class) {
-               struct kobject *kobj = NULL;
                struct kobject *parent_kobj;
                struct kobject *k;
  
        }
  
        /* subsystems can specify a default root directory for their devices */
-       if (!parent && dev->bus && dev->bus->dev_root)
-               return &dev->bus->dev_root->kobj;
+       if (!parent && dev->bus) {
+               struct device *dev_root = bus_get_dev_root(dev->bus);
+               if (dev_root) {
+                       kobj = &dev_root->kobj;
+                       put_device(dev_root);
+                       return kobj;
+               }
+       }
  
        if (parent)
                return &parent->kobj;
@@@ -3371,7 -3568,7 +3526,7 @@@ int device_add(struct device *dev
        /* we require the name to be set before, and pass NULL */
        error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
        if (error) {
-               glue_dir = get_glue_dir(dev);
+               glue_dir = kobj;
                goto Error;
        }
  
        /* Notify clients of device addition.  This call must come
         * after dpm_sysfs_add() and before kobject_uevent().
         */
-       if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
-                                            BUS_NOTIFY_ADD_DEVICE, dev);
+       bus_notify(dev, BUS_NOTIFY_ADD_DEVICE);
        kobject_uevent(&dev->kobj, KOBJ_ADD);
  
        /*
@@@ -3471,6 -3665,7 +3623,7 @@@ done
        device_pm_remove(dev);
        dpm_sysfs_remove(dev);
   DPMError:
+       dev->driver = NULL;
        bus_remove_device(dev);
   BusError:
        device_remove_attrs(dev);
@@@ -3594,9 -3789,7 +3747,7 @@@ void device_del(struct device *dev
         * before dpm_sysfs_remove().
         */
        noio_flag = memalloc_noio_save();
-       if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
-                                            BUS_NOTIFY_DEL_DEVICE, dev);
+       bus_notify(dev, BUS_NOTIFY_DEL_DEVICE);
  
        dpm_sysfs_remove(dev);
        if (parent)
        device_platform_notify_remove(dev);
        device_links_purge(dev);
  
-       if (dev->bus)
-               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
-                                            BUS_NOTIFY_REMOVED_DEVICE, dev);
+       bus_notify(dev, BUS_NOTIFY_REMOVED_DEVICE);
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        glue_dir = get_glue_dir(dev);
        kobject_del(&dev->kobj);
@@@ -3697,7 -3888,7 +3846,7 @@@ static struct device *next_device(struc
   * a name. This memory is returned in tmp and needs to be
   * freed by the caller.
   */
- const char *device_get_devnode(struct device *dev,
+ const char *device_get_devnode(const struct device *dev,
                               umode_t *mode, kuid_t *uid, kgid_t *gid,
                               const char **tmp)
  {
diff --combined drivers/base/devtmpfs.c
index 03e8a95f1f35da21e5c7ad807a712b9342455cb0,95ebc18ded5099e04ce8a7ba543d986800ef5a9d..ae72d4ba8547254290222f1de643a51103d0281c
@@@ -13,6 -13,8 +13,8 @@@
   * overwrite the default setting if needed.
   */
  
+ #define pr_fmt(fmt) "devtmpfs: " fmt
  #include <linux/kernel.h>
  #include <linux/syscalls.h>
  #include <linux/mount.h>
@@@ -173,7 -175,7 +175,7 @@@ static int dev_mkdir(const char *name, 
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
  
 -      err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
 +      err = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
        if (!err)
                /* mark as kernel-created inode */
                d_inode(dentry)->i_private = &thread;
@@@ -223,7 -225,7 +225,7 @@@ static int handle_create(const char *no
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
  
 -      err = vfs_mknod(&init_user_ns, d_inode(path.dentry), dentry, mode,
 +      err = vfs_mknod(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode,
                        dev->devt);
        if (!err) {
                struct iattr newattrs;
                newattrs.ia_gid = gid;
                newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
                inode_lock(d_inode(dentry));
 -              notify_change(&init_user_ns, dentry, &newattrs, NULL);
 +              notify_change(&nop_mnt_idmap, dentry, &newattrs, NULL);
                inode_unlock(d_inode(dentry));
  
                /* mark as kernel-created inode */
@@@ -254,7 -256,7 +256,7 @@@ static int dev_rmdir(const char *name
                return PTR_ERR(dentry);
        if (d_really_is_positive(dentry)) {
                if (d_inode(dentry)->i_private == &thread)
 -                      err = vfs_rmdir(&init_user_ns, d_inode(parent.dentry),
 +                      err = vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry),
                                        dentry);
                else
                        err = -EPERM;
@@@ -341,9 -343,9 +343,9 @@@ static int handle_remove(const char *no
                        newattrs.ia_valid =
                                ATTR_UID|ATTR_GID|ATTR_MODE;
                        inode_lock(d_inode(dentry));
 -                      notify_change(&init_user_ns, dentry, &newattrs, NULL);
 +                      notify_change(&nop_mnt_idmap, dentry, &newattrs, NULL);
                        inode_unlock(d_inode(dentry));
 -                      err = vfs_unlink(&init_user_ns, d_inode(parent.dentry),
 +                      err = vfs_unlink(&nop_mnt_idmap, d_inode(parent.dentry),
                                         dentry, NULL);
                        if (!err || err == -ENOENT)
                                deleted = 1;
@@@ -376,9 -378,9 +378,9 @@@ int __init devtmpfs_mount(void
  
        err = init_mount("devtmpfs", "dev", "devtmpfs", DEVTMPFS_MFLAGS, NULL);
        if (err)
-               printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
+               pr_info("error mounting %d\n", err);
        else
-               printk(KERN_INFO "devtmpfs: mounted\n");
+               pr_info("mounted\n");
        return err;
  }
  
@@@ -460,14 -462,12 +462,12 @@@ int __init devtmpfs_init(void
  
        mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts);
        if (IS_ERR(mnt)) {
-               printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n",
-                               PTR_ERR(mnt));
+               pr_err("unable to create devtmpfs %ld\n", PTR_ERR(mnt));
                return PTR_ERR(mnt);
        }
        err = register_filesystem(&dev_fs_type);
        if (err) {
-               printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
-                      "type %i\n", err);
+               pr_err("unable to register devtmpfs type %d\n", err);
                return err;
        }
  
        }
  
        if (err) {
-               printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
+               pr_err("unable to create devtmpfs %d\n", err);
                unregister_filesystem(&dev_fs_type);
                thread = NULL;
                return err;
        }
  
-       printk(KERN_INFO "devtmpfs: initialized\n");
+       pr_info("initialized\n");
        return 0;
  }
index dffe03658ff901be8ea4052842406141116bbec3,4819369faa8be19f4fc6b602f1212402d7f6c657..a6a48e5154784f133f66122d3faaf2bb0aea9551
@@@ -123,13 -123,6 +123,13 @@@ static int mhi_ep_process_cmd_ring(stru
        int ret;
  
        ch_id = MHI_TRE_GET_CMD_CHID(el);
 +
 +      /* Check if the channel is supported by the controller */
 +      if ((ch_id >= mhi_cntrl->max_chan) || !mhi_cntrl->mhi_chan[ch_id].name) {
 +              dev_err(dev, "Channel (%u) not supported!\n", ch_id);
 +              return -ENODEV;
 +      }
 +
        mhi_chan = &mhi_cntrl->mhi_chan[ch_id];
        ch_ring = &mhi_cntrl->mhi_chan[ch_id].ring;
  
                mhi_ep_mmio_disable_chdb(mhi_cntrl, ch_id);
  
                /* Send channel disconnect status to client drivers */
 -              result.transaction_status = -ENOTCONN;
 -              result.bytes_xferd = 0;
 -              mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
 +              if (mhi_chan->xfer_cb) {
 +                      result.transaction_status = -ENOTCONN;
 +                      result.bytes_xferd = 0;
 +                      mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
 +              }
  
                /* Set channel state to STOP */
                mhi_chan->state = MHI_CH_STATE_STOP;
                mutex_unlock(&mhi_chan->lock);
                break;
        case MHI_PKT_TYPE_RESET_CHAN_CMD:
 -              dev_dbg(dev, "Received STOP command for channel (%u)\n", ch_id);
 +              dev_dbg(dev, "Received RESET command for channel (%u)\n", ch_id);
                if (!ch_ring->started) {
                        dev_err(dev, "Channel (%u) not opened\n", ch_id);
                        return -ENODEV;
                mhi_ep_ring_reset(mhi_cntrl, ch_ring);
  
                /* Send channel disconnect status to client driver */
 -              result.transaction_status = -ENOTCONN;
 -              result.bytes_xferd = 0;
 -              mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
 +              if (mhi_chan->xfer_cb) {
 +                      result.transaction_status = -ENOTCONN;
 +                      result.bytes_xferd = 0;
 +                      mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
 +              }
  
                /* Set channel state to DISABLED */
                mhi_chan->state = MHI_CH_STATE_DISABLED;
@@@ -730,37 -719,24 +730,37 @@@ static void mhi_ep_ch_ring_worker(struc
                list_del(&itr->node);
                ring = itr->ring;
  
 +              chan = &mhi_cntrl->mhi_chan[ring->ch_id];
 +              mutex_lock(&chan->lock);
 +
 +              /*
 +               * The ring could've stopped while we waited to grab the (chan->lock), so do
 +               * a sanity check before going further.
 +               */
 +              if (!ring->started) {
 +                      mutex_unlock(&chan->lock);
 +                      kfree(itr);
 +                      continue;
 +              }
 +
                /* Update the write offset for the ring */
                ret = mhi_ep_update_wr_offset(ring);
                if (ret) {
                        dev_err(dev, "Error updating write offset for ring\n");
 +                      mutex_unlock(&chan->lock);
                        kfree(itr);
                        continue;
                }
  
                /* Sanity check to make sure there are elements in the ring */
                if (ring->rd_offset == ring->wr_offset) {
 +                      mutex_unlock(&chan->lock);
                        kfree(itr);
                        continue;
                }
  
                el = &ring->ring_cache[ring->rd_offset];
 -              chan = &mhi_cntrl->mhi_chan[ring->ch_id];
  
 -              mutex_lock(&chan->lock);
                dev_dbg(dev, "Processing the ring for channel (%u)\n", ring->ch_id);
                ret = mhi_ep_process_ch_ring(ring, el);
                if (ret) {
@@@ -997,25 -973,44 +997,25 @@@ static void mhi_ep_abort_transfer(struc
  static void mhi_ep_reset_worker(struct work_struct *work)
  {
        struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, reset_work);
 -      struct device *dev = &mhi_cntrl->mhi_dev->dev;
        enum mhi_state cur_state;
 -      int ret;
  
 -      mhi_ep_abort_transfer(mhi_cntrl);
 +      mhi_ep_power_down(mhi_cntrl);
 +
 +      mutex_lock(&mhi_cntrl->state_lock);
  
 -      spin_lock_bh(&mhi_cntrl->state_lock);
        /* Reset MMIO to signal host that the MHI_RESET is completed in endpoint */
        mhi_ep_mmio_reset(mhi_cntrl);
        cur_state = mhi_cntrl->mhi_state;
 -      spin_unlock_bh(&mhi_cntrl->state_lock);
  
        /*
         * Only proceed further if the reset is due to SYS_ERR. The host will
         * issue reset during shutdown also and we don't need to do re-init in
         * that case.
         */
 -      if (cur_state == MHI_STATE_SYS_ERR) {
 -              mhi_ep_mmio_init(mhi_cntrl);
 -
 -              /* Set AMSS EE before signaling ready state */
 -              mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS);
 -
 -              /* All set, notify the host that we are ready */
 -              ret = mhi_ep_set_ready_state(mhi_cntrl);
 -              if (ret)
 -                      return;
 -
 -              dev_dbg(dev, "READY state notification sent to the host\n");
 -
 -              ret = mhi_ep_enable(mhi_cntrl);
 -              if (ret) {
 -                      dev_err(dev, "Failed to enable MHI endpoint: %d\n", ret);
 -                      return;
 -              }
 +      if (cur_state == MHI_STATE_SYS_ERR)
 +              mhi_ep_power_up(mhi_cntrl);
  
 -              enable_irq(mhi_cntrl->irq);
 -      }
 +      mutex_unlock(&mhi_cntrl->state_lock);
  }
  
  /*
@@@ -1094,11 -1089,11 +1094,11 @@@ EXPORT_SYMBOL_GPL(mhi_ep_power_up)
  
  void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl)
  {
 -      if (mhi_cntrl->enabled)
 +      if (mhi_cntrl->enabled) {
                mhi_ep_abort_transfer(mhi_cntrl);
 -
 -      kfree(mhi_cntrl->mhi_event);
 -      disable_irq(mhi_cntrl->irq);
 +              kfree(mhi_cntrl->mhi_event);
 +              disable_irq(mhi_cntrl->irq);
 +      }
  }
  EXPORT_SYMBOL_GPL(mhi_ep_power_down);
  
@@@ -1124,7 -1119,6 +1124,7 @@@ void mhi_ep_suspend_channels(struct mhi
  
                dev_dbg(&mhi_chan->mhi_dev->dev, "Suspending channel\n");
                /* Set channel state to SUSPENDED */
 +              mhi_chan->state = MHI_CH_STATE_SUSPENDED;
                tmp &= ~CHAN_CTX_CHSTATE_MASK;
                tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_SUSPENDED);
                mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
@@@ -1154,7 -1148,6 +1154,7 @@@ void mhi_ep_resume_channels(struct mhi_
  
                dev_dbg(&mhi_chan->mhi_dev->dev, "Resuming channel\n");
                /* Set channel state to RUNNING */
 +              mhi_chan->state = MHI_CH_STATE_RUNNING;
                tmp &= ~CHAN_CTX_CHSTATE_MASK;
                tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING);
                mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
@@@ -1388,8 -1381,8 +1388,8 @@@ int mhi_ep_register_controller(struct m
  
        INIT_LIST_HEAD(&mhi_cntrl->st_transition_list);
        INIT_LIST_HEAD(&mhi_cntrl->ch_db_list);
 -      spin_lock_init(&mhi_cntrl->state_lock);
        spin_lock_init(&mhi_cntrl->list_lock);
 +      mutex_init(&mhi_cntrl->state_lock);
        mutex_init(&mhi_cntrl->event_lock);
  
        /* Set MHI version and AMSS EE before enumeration */
@@@ -1550,9 -1543,9 +1550,9 @@@ void mhi_ep_driver_unregister(struct mh
  }
  EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister);
  
- static int mhi_ep_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int mhi_ep_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
+       const struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
  
        return add_uevent_var(env, "MODALIAS=" MHI_EP_DEVICE_MODALIAS_FMT,
                                        mhi_dev->name);
index 7307335c4fd11c282d08ef7098dd279e79b79f5d,770fc81b7e960720d3641d664e62a78a569b9e10..3d779ee6396d556e9f41a1cd5f773ca4f2bc08c3
@@@ -1395,9 -1395,9 +1395,9 @@@ void mhi_driver_unregister(struct mhi_d
  }
  EXPORT_SYMBOL_GPL(mhi_driver_unregister);
  
- static int mhi_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int mhi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct mhi_device *mhi_dev = to_mhi_device(dev);
+       const struct mhi_device *mhi_dev = to_mhi_device(dev);
  
        return add_uevent_var(env, "MODALIAS=" MHI_DEVICE_MODALIAS_FMT,
                                        mhi_dev->name);
@@@ -1449,4 -1449,4 +1449,4 @@@ postcore_initcall(mhi_init)
  module_exit(mhi_exit);
  
  MODULE_LICENSE("GPL v2");
 -MODULE_DESCRIPTION("MHI Host Interface");
 +MODULE_DESCRIPTION("Modem Host Interface");
diff --combined drivers/bus/sunxi-rsb.c
index 226e87b85116ea700efa5db36d89567cf89a97d0,9aa99c369e48bc3269c542ff4ca52bebf5ae266c..696c0aefb0ca98024842216759f761ae938d057f
@@@ -172,12 -172,17 +172,17 @@@ static void sunxi_rsb_device_remove(str
        drv->remove(to_sunxi_rsb_device(dev));
  }
  
+ static int sunxi_rsb_device_modalias(const struct device *dev, struct kobj_uevent_env *env)
+ {
+       return of_device_uevent_modalias(dev, env);
+ }
  static struct bus_type sunxi_rsb_bus = {
        .name           = RSB_CTRL_NAME,
        .match          = sunxi_rsb_device_match,
        .probe          = sunxi_rsb_device_probe,
        .remove         = sunxi_rsb_device_remove,
-       .uevent         = of_device_uevent_modalias,
+       .uevent         = sunxi_rsb_device_modalias,
  };
  
  static void sunxi_rsb_dev_release(struct device *dev)
@@@ -857,13 -862,7 +862,13 @@@ static int __init sunxi_rsb_init(void
                return ret;
        }
  
 -      return platform_driver_register(&sunxi_rsb_driver);
 +      ret = platform_driver_register(&sunxi_rsb_driver);
 +      if (ret) {
 +              bus_unregister(&sunxi_rsb_bus);
 +              return ret;
 +      }
 +
 +      return 0;
  }
  module_init(sunxi_rsb_init);
  
diff --combined drivers/fpga/dfl.c
index b010f0a83a7858f15906fc2ada56246930a0dda7,4d32c98c82fcf8f4d6b039151adb2e42a8aec2bf..dd7a783d53b5f4d865251ec34a3c390770c9c0a2
@@@ -13,7 -13,6 +13,7 @@@
  #include <linux/dfl.h>
  #include <linux/fpga-dfl.h>
  #include <linux/module.h>
 +#include <linux/overflow.h>
  #include <linux/uaccess.h>
  
  #include "dfl.h"
@@@ -46,7 -45,7 +46,7 @@@ static const char *dfl_pdata_key_string
  };
  
  /**
 - * dfl_dev_info - dfl feature device information.
 + * struct dfl_dev_info - dfl feature device information.
   * @name: name string of the feature platform device.
   * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec.
   * @id: idr id of the feature dev.
@@@ -68,7 -67,7 +68,7 @@@ static struct dfl_dev_info dfl_devs[] 
  };
  
  /**
 - * dfl_chardev_info - chardev information of dfl feature device
 + * struct dfl_chardev_info - chardev information of dfl feature device
   * @name: nmae string of the char device.
   * @devt: devt of the char device.
   */
@@@ -294,9 -293,9 +294,9 @@@ static void dfl_bus_remove(struct devic
                ddrv->remove(ddev);
  }
  
- static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int dfl_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct dfl_device *ddev = to_dfl_dev(dev);
+       const struct dfl_device *ddev = to_dfl_dev(dev);
  
        return add_uevent_var(env, "MODALIAS=dfl:t%04Xf%04X",
                              ddev->type, ddev->feature_id);
@@@ -343,8 -342,6 +343,8 @@@ static void release_dfl_dev(struct devi
        if (ddev->mmio_res.parent)
                release_resource(&ddev->mmio_res);
  
 +      kfree(ddev->params);
 +
        ida_free(&dfl_device_ida, ddev->id);
        kfree(ddev->irqs);
        kfree(ddev);
@@@ -383,16 -380,7 +383,16 @@@ dfl_dev_add(struct dfl_feature_platform
        ddev->type = feature_dev_id_type(pdev);
        ddev->feature_id = feature->id;
        ddev->revision = feature->revision;
 +      ddev->dfh_version = feature->dfh_version;
        ddev->cdev = pdata->dfl_cdev;
 +      if (feature->param_size) {
 +              ddev->params = kmemdup(feature->params, feature->param_size, GFP_KERNEL);
 +              if (!ddev->params) {
 +                      ret = -ENOMEM;
 +                      goto put_dev;
 +              }
 +              ddev->param_size = feature->param_size;
 +      }
  
        /* add mmio resource */
        parent_res = &pdev->resource[feature->resource_index];
@@@ -720,27 -708,20 +720,27 @@@ struct build_feature_devs_info 
   * struct dfl_feature_info - sub feature info collected during feature dev build
   *
   * @fid: id of this sub feature.
 + * @revision: revision of this sub feature
 + * @dfh_version: version of Device Feature Header (DFH)
   * @mmio_res: mmio resource of this sub feature.
   * @ioaddr: mapped base address of mmio resource.
   * @node: node in sub_features linked list.
   * @irq_base: start of irq index in this sub feature.
   * @nr_irqs: number of irqs of this sub feature.
 + * @param_size: size DFH parameters.
 + * @params: DFH parameter data.
   */
  struct dfl_feature_info {
        u16 fid;
        u8 revision;
 +      u8 dfh_version;
        struct resource mmio_res;
        void __iomem *ioaddr;
        struct list_head node;
        unsigned int irq_base;
        unsigned int nr_irqs;
 +      unsigned int param_size;
 +      u64 params[];
  };
  
  static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev,
@@@ -816,17 -797,7 +816,17 @@@ static int build_info_commit_dev(struc
                feature->dev = fdev;
                feature->id = finfo->fid;
                feature->revision = finfo->revision;
 +              feature->dfh_version = finfo->dfh_version;
  
 +              if (finfo->param_size) {
 +                      feature->params = devm_kmemdup(binfo->dev,
 +                                                     finfo->params, finfo->param_size,
 +                                                     GFP_KERNEL);
 +                      if (!feature->params)
 +                              return -ENOMEM;
 +
 +                      feature->param_size = finfo->param_size;
 +              }
                /*
                 * the FIU header feature has some fundamental functions (sriov
                 * set, port enable/disable) needed for the dfl bus device and
@@@ -963,115 -934,56 +963,115 @@@ static u16 feature_id(u64 value
        return 0;
  }
  
 +static u64 *find_param(u64 *params, resource_size_t max, int param_id)
 +{
 +      u64 *end = params + max / sizeof(u64);
 +      u64 v, next;
 +
 +      while (params < end) {
 +              v = *params;
 +              if (param_id == FIELD_GET(DFHv1_PARAM_HDR_ID, v))
 +                      return params;
 +
 +              if (FIELD_GET(DFHv1_PARAM_HDR_NEXT_EOP, v))
 +                      break;
 +
 +              next = FIELD_GET(DFHv1_PARAM_HDR_NEXT_OFFSET, v);
 +              params += next;
 +      }
 +
 +      return NULL;
 +}
 +
 +/**
 + * dfh_find_param() - find parameter block for the given parameter id
 + * @dfl_dev: dfl device
 + * @param_id: id of dfl parameter
 + * @psize: destination to store size of parameter data in bytes
 + *
 + * Return: pointer to start of parameter data, PTR_ERR otherwise.
 + */
 +void *dfh_find_param(struct dfl_device *dfl_dev, int param_id, size_t *psize)
 +{
 +      u64 *phdr = find_param(dfl_dev->params, dfl_dev->param_size, param_id);
 +
 +      if (!phdr)
 +              return ERR_PTR(-ENOENT);
 +
 +      if (psize)
 +              *psize = (FIELD_GET(DFHv1_PARAM_HDR_NEXT_OFFSET, *phdr) - 1) * sizeof(u64);
 +
 +      return phdr + 1;
 +}
 +EXPORT_SYMBOL_GPL(dfh_find_param);
 +
  static int parse_feature_irqs(struct build_feature_devs_info *binfo,
 -                            resource_size_t ofst, u16 fid,
 -                            unsigned int *irq_base, unsigned int *nr_irqs)
 +                            resource_size_t ofst, struct dfl_feature_info *finfo)
  {
        void __iomem *base = binfo->ioaddr + ofst;
        unsigned int i, ibase, inr = 0;
 +      void *params = finfo->params;
        enum dfl_id_type type;
 +      u16 fid = finfo->fid;
        int virq;
 +      u64 *p;
        u64 v;
  
 -      type = feature_dev_id_type(binfo->feature_dev);
 +      switch (finfo->dfh_version) {
 +      case 0:
 +              /*
 +               * DFHv0 only provides MMIO resource information for each feature
 +               * in the DFL header.  There is no generic interrupt information.
 +               * Instead, features with interrupt functionality provide
 +               * the information in feature specific registers.
 +               */
 +              type = feature_dev_id_type(binfo->feature_dev);
 +              if (type == PORT_ID) {
 +                      switch (fid) {
 +                      case PORT_FEATURE_ID_UINT:
 +                              v = readq(base + PORT_UINT_CAP);
 +                              ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
 +                              inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
 +                              break;
 +                      case PORT_FEATURE_ID_ERROR:
 +                              v = readq(base + PORT_ERROR_CAP);
 +                              ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
 +                              inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
 +                              break;
 +                      }
 +              } else if (type == FME_ID) {
 +                      switch (fid) {
 +                      case FME_FEATURE_ID_GLOBAL_ERR:
 +                              v = readq(base + FME_ERROR_CAP);
 +                              ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
 +                              inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
 +                              break;
 +                      }
 +              }
 +              break;
  
 -      /*
 -       * Ideally DFL framework should only read info from DFL header, but
 -       * current version DFL only provides mmio resources information for
 -       * each feature in DFL Header, no field for interrupt resources.
 -       * Interrupt resource information is provided by specific mmio
 -       * registers of each private feature which supports interrupt. So in
 -       * order to parse and assign irq resources, DFL framework has to look
 -       * into specific capability registers of these private features.
 -       *
 -       * Once future DFL version supports generic interrupt resource
 -       * information in common DFL headers, the generic interrupt parsing
 -       * code will be added. But in order to be compatible to old version
 -       * DFL, the driver may still fall back to these quirks.
 -       */
 -      if (type == PORT_ID) {
 -              switch (fid) {
 -              case PORT_FEATURE_ID_UINT:
 -                      v = readq(base + PORT_UINT_CAP);
 -                      ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
 -                      inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
 -                      break;
 -              case PORT_FEATURE_ID_ERROR:
 -                      v = readq(base + PORT_ERROR_CAP);
 -                      ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
 -                      inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
 +      case 1:
 +              /*
 +               * DFHv1 provides interrupt resource information in DFHv1
 +               * parameter blocks.
 +               */
 +              p = find_param(params, finfo->param_size, DFHv1_PARAM_ID_MSI_X);
 +              if (!p)
                        break;
 -              }
 -      } else if (type == FME_ID) {
 -              if (fid == FME_FEATURE_ID_GLOBAL_ERR) {
 -                      v = readq(base + FME_ERROR_CAP);
 -                      ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
 -                      inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
 -              }
 +
 +              p++;
 +              ibase = FIELD_GET(DFHv1_PARAM_MSI_X_STARTV, *p);
 +              inr = FIELD_GET(DFHv1_PARAM_MSI_X_NUMV, *p);
 +              break;
 +
 +      default:
 +              dev_warn(binfo->dev, "unexpected DFH version %d\n", finfo->dfh_version);
 +              break;
        }
  
        if (!inr) {
 -              *irq_base = 0;
 -              *nr_irqs = 0;
 +              finfo->irq_base = 0;
 +              finfo->nr_irqs = 0;
                return 0;
        }
  
                }
        }
  
 -      *irq_base = ibase;
 -      *nr_irqs = inr;
 +      finfo->irq_base = ibase;
 +      finfo->nr_irqs = inr;
  
        return 0;
  }
  
 +static int dfh_get_param_size(void __iomem *dfh_base, resource_size_t max)
 +{
 +      int size = 0;
 +      u64 v, next;
 +
 +      if (!FIELD_GET(DFHv1_CSR_SIZE_GRP_HAS_PARAMS,
 +                     readq(dfh_base + DFHv1_CSR_SIZE_GRP)))
 +              return 0;
 +
 +      while (size + DFHv1_PARAM_HDR < max) {
 +              v = readq(dfh_base + DFHv1_PARAM_HDR + size);
 +
 +              next = FIELD_GET(DFHv1_PARAM_HDR_NEXT_OFFSET, v);
 +              if (!next)
 +                      return -EINVAL;
 +
 +              size += next * sizeof(u64);
 +
 +              if (FIELD_GET(DFHv1_PARAM_HDR_NEXT_EOP, v))
 +                      return size;
 +      }
 +
 +      return -ENOENT;
 +}
 +
  /*
   * when create sub feature instances, for private features, it doesn't need
   * to provide resource size and feature id as they could be read from DFH
@@@ -1136,69 -1023,39 +1136,69 @@@ static in
  create_feature_instance(struct build_feature_devs_info *binfo,
                        resource_size_t ofst, resource_size_t size, u16 fid)
  {
 -      unsigned int irq_base, nr_irqs;
        struct dfl_feature_info *finfo;
 +      resource_size_t start, end;
 +      int dfh_psize = 0;
        u8 revision = 0;
 +      u64 v, addr_off;
 +      u8 dfh_ver = 0;
        int ret;
 -      u64 v;
  
        if (fid != FEATURE_ID_AFU) {
                v = readq(binfo->ioaddr + ofst);
                revision = FIELD_GET(DFH_REVISION, v);
 -
 +              dfh_ver = FIELD_GET(DFH_VERSION, v);
                /* read feature size and id if inputs are invalid */
                size = size ? size : feature_size(v);
                fid = fid ? fid : feature_id(v);
 +              if (dfh_ver == 1) {
 +                      dfh_psize = dfh_get_param_size(binfo->ioaddr + ofst, size);
 +                      if (dfh_psize < 0) {
 +                              dev_err(binfo->dev,
 +                                      "failed to read size of DFHv1 parameters %d\n",
 +                                      dfh_psize);
 +                              return dfh_psize;
 +                      }
 +                      dev_dbg(binfo->dev, "dfhv1_psize %d\n", dfh_psize);
 +              }
        }
  
        if (binfo->len - ofst < size)
                return -EINVAL;
  
 -      ret = parse_feature_irqs(binfo, ofst, fid, &irq_base, &nr_irqs);
 -      if (ret)
 -              return ret;
 -
 -      finfo = kzalloc(sizeof(*finfo), GFP_KERNEL);
 +      finfo = kzalloc(struct_size(finfo, params, dfh_psize / sizeof(u64)), GFP_KERNEL);
        if (!finfo)
                return -ENOMEM;
  
 +      memcpy_fromio(finfo->params, binfo->ioaddr + ofst + DFHv1_PARAM_HDR, dfh_psize);
 +      finfo->param_size = dfh_psize;
 +
        finfo->fid = fid;
        finfo->revision = revision;
 -      finfo->mmio_res.start = binfo->start + ofst;
 -      finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
 +      finfo->dfh_version = dfh_ver;
 +      if (dfh_ver == 1) {
 +              v = readq(binfo->ioaddr + ofst + DFHv1_CSR_ADDR);
 +              addr_off = FIELD_GET(DFHv1_CSR_ADDR_MASK, v);
 +              if (FIELD_GET(DFHv1_CSR_ADDR_REL, v))
 +                      start = addr_off << 1;
 +              else
 +                      start = binfo->start + ofst + addr_off;
 +
 +              v = readq(binfo->ioaddr + ofst + DFHv1_CSR_SIZE_GRP);
 +              end = start + FIELD_GET(DFHv1_CSR_SIZE_GRP_SIZE, v) - 1;
 +      } else {
 +              start = binfo->start + ofst;
 +              end = start + size - 1;
 +      }
        finfo->mmio_res.flags = IORESOURCE_MEM;
 -      finfo->irq_base = irq_base;
 -      finfo->nr_irqs = nr_irqs;
 +      finfo->mmio_res.start = start;
 +      finfo->mmio_res.end = end;
 +
 +      ret = parse_feature_irqs(binfo, ofst, finfo);
 +      if (ret) {
 +              kfree(finfo);
 +              return ret;
 +      }
  
        list_add_tail(&finfo->node, &binfo->sub_features);
        binfo->feature_num++;
diff --combined drivers/gpio/gpiolib.c
index 99a2c77c3711b6e3371fdfd4e60957b30447b1b8,bdb9493857ebbcc8f0163718e1bc18c67e715039..19bd23044b01712dd445a082787b5a1eba6bd1ae
@@@ -1,35 -1,34 +1,35 @@@
  // SPDX-License-Identifier: GPL-2.0
  
 +#include <linux/acpi.h>
  #include <linux/bitmap.h>
 -#include <linux/kernel.h>
 -#include <linux/module.h>
 -#include <linux/interrupt.h>
 -#include <linux/irq.h>
 -#include <linux/spinlock.h>
 -#include <linux/list.h>
 +#include <linux/compat.h>
 +#include <linux/debugfs.h>
  #include <linux/device.h>
  #include <linux/err.h>
 -#include <linux/debugfs.h>
 -#include <linux/seq_file.h>
 +#include <linux/file.h>
 +#include <linux/fs.h>
  #include <linux/gpio.h>
 -#include <linux/idr.h>
 -#include <linux/slab.h>
 -#include <linux/acpi.h>
  #include <linux/gpio/driver.h>
  #include <linux/gpio/machine.h>
 +#include <linux/idr.h>
 +#include <linux/interrupt.h>
 +#include <linux/irq.h>
 +#include <linux/kernel.h>
 +#include <linux/list.h>
 +#include <linux/module.h>
  #include <linux/pinctrl/consumer.h>
 -#include <linux/fs.h>
 -#include <linux/compat.h>
 -#include <linux/file.h>
 +#include <linux/seq_file.h>
 +#include <linux/slab.h>
 +#include <linux/spinlock.h>
 +
  #include <uapi/linux/gpio.h>
  
 -#include "gpiolib.h"
 -#include "gpiolib-of.h"
  #include "gpiolib-acpi.h"
 -#include "gpiolib-swnode.h"
  #include "gpiolib-cdev.h"
 +#include "gpiolib-of.h"
 +#include "gpiolib-swnode.h"
  #include "gpiolib-sysfs.h"
 +#include "gpiolib.h"
  
  #define CREATE_TRACE_POINTS
  #include <trace/events/gpio.h>
@@@ -532,14 -531,6 +532,14 @@@ static void gpiochip_free_valid_mask(st
  
  static int gpiochip_add_pin_ranges(struct gpio_chip *gc)
  {
 +      /*
 +       * Device Tree platforms are supposed to use "gpio-ranges"
 +       * property. This check ensures that the ->add_pin_ranges()
 +       * won't be called for them.
 +       */
 +      if (device_property_present(&gc->gpiodev->dev, "gpio-ranges"))
 +              return 0;
 +
        if (gc->add_pin_ranges)
                return gc->add_pin_ranges(gc);
  
@@@ -587,6 -578,13 +587,13 @@@ static int gpiochip_setup_dev(struct gp
  {
        int ret;
  
+       /*
+        * If fwnode doesn't belong to another device, it's safe to clear its
+        * initialized flag.
+        */
+       if (gdev->dev.fwnode && !gdev->dev.fwnode->dev)
+               fwnode_dev_initialized(gdev->dev.fwnode, false);
        ret = gcdev_register(gdev, gpio_devt);
        if (ret)
                return ret;
@@@ -668,12 -666,10 +675,12 @@@ int gpiochip_add_data_with_key(struct g
        int base = 0;
        int ret = 0;
  
 +      /* If the calling driver did not initialize firmware node, do it here */
        if (gc->fwnode)
                fwnode = gc->fwnode;
        else if (gc->parent)
                fwnode = dev_fwnode(gc->parent);
 +      gc->fwnode = fwnode;
  
        /*
         * First: allocate and populate the internal stat container, and
        gdev->chip = gc;
        gc->gpiodev = gdev;
  
 -      of_gpio_dev_init(gc, gdev);
 -      acpi_gpio_dev_init(gc, gdev);
 -
 -      /*
 -       * Assign fwnode depending on the result of the previous calls,
 -       * if none of them succeed, assign it to the parent's one.
 -       */
 -      gc->fwnode = gdev->dev.fwnode = dev_fwnode(&gdev->dev) ?: fwnode;
 +      device_set_node(&gdev->dev, gc->fwnode);
  
        gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
        if (gdev->id < 0) {
@@@ -886,7 -889,7 +893,7 @@@ err_free_gpiochip_mask
        gpiochip_free_valid_mask(gc);
        if (gdev->dev.release) {
                /* release() has been registered by gpiochip_setup_dev() */
 -              put_device(&gdev->dev);
 +              gpio_device_put(gdev);
                goto err_print_message;
        }
  err_remove_from_list:
@@@ -976,7 -979,7 +983,7 @@@ void gpiochip_remove(struct gpio_chip *
         */
        gcdev_unregister(gdev);
        up_write(&gdev->sem);
 -      put_device(&gdev->dev);
 +      gpio_device_put(gdev);
  }
  EXPORT_SYMBOL_GPL(gpiochip_remove);
  
@@@ -1130,8 -1133,14 +1137,8 @@@ static void gpiochip_set_hierarchical_i
                        /* Just pick something */
                        fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
                        fwspec.param_count = 2;
 -                      ret = __irq_domain_alloc_irqs(gc->irq.domain,
 -                                                    /* just pick something */
 -                                                    -1,
 -                                                    1,
 -                                                    NUMA_NO_NODE,
 -                                                    &fwspec,
 -                                                    false,
 -                                                    NULL);
 +                      ret = irq_domain_alloc_irqs(gc->irq.domain, 1,
 +                                                  NUMA_NO_NODE, &fwspec);
                        if (ret < 0) {
                                chip_err(gc,
                                         "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
@@@ -2061,15 -2070,17 +2068,15 @@@ static int validate_desc(const struct g
  int gpiod_request(struct gpio_desc *desc, const char *label)
  {
        int ret = -EPROBE_DEFER;
 -      struct gpio_device *gdev;
  
        VALIDATE_DESC(desc);
 -      gdev = desc->gdev;
  
 -      if (try_module_get(gdev->owner)) {
 +      if (try_module_get(desc->gdev->owner)) {
                ret = gpiod_request_commit(desc, label);
                if (ret)
 -                      module_put(gdev->owner);
 +                      module_put(desc->gdev->owner);
                else
 -                      get_device(&gdev->dev);
 +                      gpio_device_get(desc->gdev);
        }
  
        if (ret)
@@@ -2130,7 -2141,7 +2137,7 @@@ void gpiod_free(struct gpio_desc *desc
  {
        if (desc && desc->gdev && gpiod_free_commit(desc)) {
                module_put(desc->gdev->owner);
 -              put_device(&desc->gdev->dev);
 +              gpio_device_put(desc->gdev);
        } else {
                WARN_ON(extra_checks);
        }
index 4bc15fbd009d866e9240bd708074c1acc28750ee,36c24c2b0899f7a365730fad4b399433ee2ccf62..b41aaf2bb9f164d29bfcf1fe2b1cb73192de7d83
@@@ -62,9 -62,9 +62,9 @@@ static int mipi_dsi_device_match(struc
        return 0;
  }
  
- static int mipi_dsi_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int mipi_dsi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+       const struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
        int err;
  
        err = of_device_uevent_modalias(dev, env);
@@@ -1224,58 -1224,6 +1224,58 @@@ int mipi_dsi_dcs_get_display_brightness
  }
  EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness);
  
 +/**
 + * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value
 + *    of the display
 + * @dsi: DSI peripheral device
 + * @brightness: brightness value
 + *
 + * Return: 0 on success or a negative error code on failure.
 + */
 +int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
 +                                           u16 brightness)
 +{
 +      u8 payload[2] = { brightness >> 8, brightness & 0xff };
 +      ssize_t err;
 +
 +      err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
 +                               payload, sizeof(payload));
 +      if (err < 0)
 +              return err;
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large);
 +
 +/**
 + * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit
 + *    brightness value of the display
 + * @dsi: DSI peripheral device
 + * @brightness: brightness value
 + *
 + * Return: 0 on success or a negative error code on failure.
 + */
 +int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 +                                           u16 *brightness)
 +{
 +      u8 brightness_be[2];
 +      ssize_t err;
 +
 +      err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
 +                              brightness_be, sizeof(brightness_be));
 +      if (err <= 0) {
 +              if (err == 0)
 +                      err = -ENODATA;
 +
 +              return err;
 +      }
 +
 +      *brightness = (brightness_be[0] << 8) | brightness_be[1];
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
 +
  static int mipi_dsi_drv_probe(struct device *dev)
  {
        struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --combined drivers/hid/hid-core.c
index 1ee623c26c49d22c22aef92091d580137af0fc3c,a45e7034f0852b638ef1632577c81c2d3ac04abe..842afc88a9496c382cb936fd24b78baef054e2bd
  
  #define DRIVER_DESC "HID core driver"
  
 -int hid_debug = 0;
 -module_param_named(debug, hid_debug, int, 0600);
 -MODULE_PARM_DESC(debug, "toggle HID debugging messages");
 -EXPORT_SYMBOL_GPL(hid_debug);
 -
  static int hid_ignore_special_drivers = 0;
  module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
  MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver");
@@@ -799,8 -804,7 +799,8 @@@ static void hid_scan_collection(struct 
        int i;
  
        if (((parser->global.usage_page << 16) == HID_UP_SENSOR) &&
 -          type == HID_COLLECTION_PHYSICAL)
 +          (type == HID_COLLECTION_PHYSICAL ||
 +           type == HID_COLLECTION_APPLICATION))
                hid->group = HID_GROUP_SENSOR_HUB;
  
        if (hid->vendor == USB_VENDOR_ID_MICROSOFT &&
@@@ -1198,7 -1202,6 +1198,7 @@@ int hid_open_report(struct hid_device *
        __u8 *end;
        __u8 *next;
        int ret;
 +      int i;
        static int (*dispatch_type[])(struct hid_parser *parser,
                                      struct hid_item *item) = {
                hid_parser_main,
                return -ENODEV;
        size = device->dev_rsize;
  
 -      buf = kmemdup(start, size, GFP_KERNEL);
 +      /* call_hid_bpf_rdesc_fixup() ensures we work on a copy of rdesc */
 +      buf = call_hid_bpf_rdesc_fixup(device, start, &size);
        if (buf == NULL)
                return -ENOMEM;
  
                goto err;
        }
        device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
 +      for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++)
 +              device->collection[i].parent_idx = -1;
  
        ret = -EINVAL;
        while ((next = fetch_item(start, end, &item)) != NULL) {
@@@ -2043,12 -2043,6 +2043,12 @@@ int hid_input_report(struct hid_device 
        report_enum = hid->report_enum + type;
        hdrv = hid->driver;
  
 +      data = dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt);
 +      if (IS_ERR(data)) {
 +              ret = PTR_ERR(data);
 +              goto unlock;
 +      }
 +
        if (!size) {
                dbg_hid("empty report\n");
                ret = -1;
@@@ -2163,10 -2157,6 +2163,10 @@@ int hid_connect(struct hid_device *hdev
        int len;
        int ret;
  
 +      ret = hid_bpf_connect_device(hdev);
 +      if (ret)
 +              return ret;
 +
        if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
                connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
        if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE)
@@@ -2268,8 -2258,6 +2268,8 @@@ void hid_disconnect(struct hid_device *
        if (hdev->claimed & HID_CLAIMED_HIDRAW)
                hidraw_disconnect(hdev);
        hdev->claimed = 0;
 +
 +      hid_bpf_disconnect_device(hdev);
  }
  EXPORT_SYMBOL_GPL(hid_disconnect);
  
@@@ -2676,9 -2664,9 +2676,9 @@@ static const struct attribute_group hid
  };
  __ATTRIBUTE_GROUPS(hid_dev);
  
- static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int hid_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct hid_device *hdev = to_hid_device(dev);
+       const struct hid_device *hdev = to_hid_device(dev);
  
        if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X",
                        hdev->bus, hdev->vendor, hdev->product))
@@@ -2805,8 -2793,6 +2805,8 @@@ struct hid_device *hid_allocate_device(
        sema_init(&hdev->driver_input_lock, 1);
        mutex_init(&hdev->ll_open_lock);
  
 +      hid_bpf_device_init(hdev);
 +
        return hdev;
  }
  EXPORT_SYMBOL_GPL(hid_allocate_device);
@@@ -2833,7 -2819,6 +2833,7 @@@ static void hid_remove_device(struct hi
   */
  void hid_destroy_device(struct hid_device *hdev)
  {
 +      hid_bpf_destroy_device(hdev);
        hid_remove_device(hdev);
        put_device(&hdev->dev);
  }
@@@ -2920,29 -2905,20 +2920,29 @@@ int hid_check_keys_pressed(struct hid_d
  }
  EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
  
 +#ifdef CONFIG_HID_BPF
 +static struct hid_bpf_ops hid_ops = {
 +      .hid_get_report = hid_get_report,
 +      .hid_hw_raw_request = hid_hw_raw_request,
 +      .owner = THIS_MODULE,
 +      .bus_type = &hid_bus_type,
 +};
 +#endif
 +
  static int __init hid_init(void)
  {
        int ret;
  
 -      if (hid_debug)
 -              pr_warn("hid_debug is now used solely for parser and driver debugging.\n"
 -                      "debugfs is now used for inspecting the device (report descriptor, reports)\n");
 -
        ret = bus_register(&hid_bus_type);
        if (ret) {
                pr_err("can't register hid bus\n");
                goto err;
        }
  
 +#ifdef CONFIG_HID_BPF
 +      hid_bpf_ops = &hid_ops;
 +#endif
 +
        ret = hidraw_init();
        if (ret)
                goto err_bus;
@@@ -2958,9 -2934,6 +2958,9 @@@ err
  
  static void __exit hid_exit(void)
  {
 +#ifdef CONFIG_HID_BPF
 +      hid_bpf_ops = NULL;
 +#endif
        hid_debug_exit();
        hidraw_exit();
        bus_unregister(&hid_bus_type);
diff --combined drivers/hv/vmbus_drv.c
index 1901556efe791ccbc445947caeb7d902058a3f01,f50aaa189df66f4a4c177e3de314562c83283d81..d24dd65b33d4d334f77d86f662151fd88efc9911
@@@ -711,9 -711,9 +711,9 @@@ __ATTRIBUTE_GROUPS(vmbus_bus)
   * representation of the device guid (each byte of the guid will be
   * represented with two hex characters.
   */
- static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
+ static int vmbus_uevent(const struct device *device, struct kobj_uevent_env *env)
  {
-       struct hv_device *dev = device_to_hv_device(device);
+       const struct hv_device *dev = device_to_hv_device(device);
        const char *format = "MODALIAS=vmbus:%*phN";
  
        return add_uevent_var(env, format, UUID_SIZE, &dev->dev_type);
@@@ -2744,7 -2744,7 +2744,7 @@@ static int __init hv_acpi_init(void
        if (!hv_is_hyperv_initialized())
                return -ENODEV;
  
 -      if (hv_root_partition)
 +      if (hv_root_partition && !hv_nested)
                return 0;
  
        /*
index b47e255fc6f176313b2d46c5915d79ac8d784992,51b78a52ab7fc1106470693ed942b3286b308698..734d8e6ad4a98a9c04ca2a6eb11171d149d24b8d
@@@ -136,9 -136,9 +136,9 @@@ static int i2c_device_match(struct devi
        return 0;
  }
  
- static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int i2c_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct i2c_client *client = to_i2c_client(dev);
+       const struct i2c_client *client = to_i2c_client(dev);
        int rc;
  
        rc = of_device_uevent_modalias(dev, env);
@@@ -1012,35 -1012,6 +1012,35 @@@ void i2c_unregister_device(struct i2c_c
  }
  EXPORT_SYMBOL_GPL(i2c_unregister_device);
  
 +/**
 + * i2c_find_device_by_fwnode() - find an i2c_client for the fwnode
 + * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_client
 + *
 + * Look up and return the &struct i2c_client corresponding to the @fwnode.
 + * If no client can be found, or @fwnode is NULL, this returns NULL.
 + *
 + * The user must call put_device(&client->dev) once done with the i2c client.
 + */
 +struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode)
 +{
 +      struct i2c_client *client;
 +      struct device *dev;
 +
 +      if (!fwnode)
 +              return NULL;
 +
 +      dev = bus_find_device_by_fwnode(&i2c_bus_type, fwnode);
 +      if (!dev)
 +              return NULL;
 +
 +      client = i2c_verify_client(dev);
 +      if (!client)
 +              put_device(dev);
 +
 +      return client;
 +}
 +EXPORT_SYMBOL(i2c_find_device_by_fwnode);
 +
  
  static const struct i2c_device_id dummy_id[] = {
        { "dummy", 0 },
@@@ -1790,75 -1761,6 +1790,75 @@@ int devm_i2c_add_adapter(struct device 
  }
  EXPORT_SYMBOL_GPL(devm_i2c_add_adapter);
  
 +static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data)
 +{
 +      if (dev_fwnode(dev) == data)
 +              return 1;
 +
 +      if (dev->parent && dev_fwnode(dev->parent) == data)
 +              return 1;
 +
 +      return 0;
 +}
 +
 +/**
 + * i2c_find_adapter_by_fwnode() - find an i2c_adapter for the fwnode
 + * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter
 + *
 + * Look up and return the &struct i2c_adapter corresponding to the @fwnode.
 + * If no adapter can be found, or @fwnode is NULL, this returns NULL.
 + *
 + * The user must call put_device(&adapter->dev) once done with the i2c adapter.
 + */
 +struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode)
 +{
 +      struct i2c_adapter *adapter;
 +      struct device *dev;
 +
 +      if (!fwnode)
 +              return NULL;
 +
 +      dev = bus_find_device(&i2c_bus_type, NULL, fwnode,
 +                            i2c_dev_or_parent_fwnode_match);
 +      if (!dev)
 +              return NULL;
 +
 +      adapter = i2c_verify_adapter(dev);
 +      if (!adapter)
 +              put_device(dev);
 +
 +      return adapter;
 +}
 +EXPORT_SYMBOL(i2c_find_adapter_by_fwnode);
 +
 +/**
 + * i2c_get_adapter_by_fwnode() - find an i2c_adapter for the fwnode
 + * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter
 + *
 + * Look up and return the &struct i2c_adapter corresponding to the @fwnode,
 + * and increment the adapter module's use count. If no adapter can be found,
 + * or @fwnode is NULL, this returns NULL.
 + *
 + * The user must call i2c_put_adapter(adapter) once done with the i2c adapter.
 + * Note that this is different from i2c_find_adapter_by_node().
 + */
 +struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode)
 +{
 +      struct i2c_adapter *adapter;
 +
 +      adapter = i2c_find_adapter_by_fwnode(fwnode);
 +      if (!adapter)
 +              return NULL;
 +
 +      if (!try_module_get(adapter->owner)) {
 +              put_device(&adapter->dev);
 +              adapter = NULL;
 +      }
 +
 +      return adapter;
 +}
 +EXPORT_SYMBOL(i2c_get_adapter_by_fwnode);
 +
  static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p,
                            u32 def_val, bool use_def)
  {
diff --combined drivers/misc/mei/bus.c
index 71d53d7ffdba460db5ee6010ed64631ddd2ebfbf,706ae85ca8f5c0158933378757d7ace8ffded30e..5d7a68674d9b20b32c415fe8c132ea3c558f03e0
@@@ -1,6 -1,6 +1,6 @@@
  // SPDX-License-Identifier: GPL-2.0
  /*
 - * Copyright (c) 2012-2019, Intel Corporation. All rights reserved.
 + * Copyright (c) 2012-2023, Intel Corporation. All rights reserved.
   * Intel Management Engine Interface (Intel MEI) Linux driver
   */
  
@@@ -1227,9 -1227,9 +1227,9 @@@ ATTRIBUTE_GROUPS(mei_cldev)
   *
   * Return: 0 on success -ENOMEM on when add_uevent_var fails
   */
- static int mei_cl_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int mei_cl_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct mei_cl_device *cldev = to_mei_cl_device(dev);
+       const struct mei_cl_device *cldev = to_mei_cl_device(dev);
        const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
        u8 version = mei_me_cl_ver(cldev->me_cl);
  
@@@ -1392,7 -1392,6 +1392,7 @@@ static int mei_cl_bus_dev_add(struct me
   */
  static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev)
  {
 +      cldev->do_match = 0;
        if (cldev->is_added)
                device_release_driver(&cldev->dev);
  }
index f191a2a76f3bb2f5d99b22c68bb8d86457fe4f72,5ec4e4ca52f08de0b0fe84f56344fabb0558911d..47a48e902a243bb13fb33dcc4d1c592af1e17da7
@@@ -120,9 -120,9 +120,9 @@@ static int sdio_bus_match(struct devic
  }
  
  static int
- sdio_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+ sdio_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct sdio_func *func = dev_to_sdio_func(dev);
+       const struct sdio_func *func = dev_to_sdio_func(dev);
        unsigned int i;
  
        if (add_uevent_var(env,
@@@ -294,12 -294,6 +294,12 @@@ static void sdio_release_func(struct de
        if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
                sdio_free_func_cis(func);
  
 +      /*
 +       * We have now removed the link to the tuples in the
 +       * card structure, so remove the reference.
 +       */
 +      put_device(&func->card->dev);
 +
        kfree(func->info);
        kfree(func->tmpbuf);
        kfree(func);
@@@ -330,12 -324,6 +330,12 @@@ struct sdio_func *sdio_alloc_func(struc
  
        device_initialize(&func->dev);
  
 +      /*
 +       * We may link to tuples in the card structure,
 +       * we need make sure we have a reference to it.
 +       */
 +      get_device(&func->card->dev);
 +
        func->dev.parent = &card->dev;
        func->dev.bus = &sdio_bus_type;
        func->dev.release = sdio_release_func;
@@@ -389,9 -377,10 +389,9 @@@ int sdio_add_func(struct sdio_func *fun
   */
  void sdio_remove_func(struct sdio_func *func)
  {
 -      if (!sdio_func_present(func))
 -              return;
 +      if (sdio_func_present(func))
 +              device_del(&func->dev);
  
 -      device_del(&func->dev);
        of_node_put(func->dev.of_node);
        put_device(&func->dev);
  }
index 00d5bcdf0e6f54ee9fc69f7660137330d67f2e5b,22b352c57ca2d5e549ea277545d43884a060f325..389f33a12534419ded1015b780fd4dbb1b32a55c
@@@ -19,7 -19,6 +19,7 @@@
  #include <linux/interrupt.h>
  #include <linux/io.h>
  #include <linux/kernel.h>
 +#include <linux/micrel_phy.h>
  #include <linux/mii.h>
  #include <linux/mm.h>
  #include <linux/module.h>
@@@ -109,10 -108,9 +109,10 @@@ EXPORT_SYMBOL(mdiobus_unregister_device
  
  struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
  {
 +      bool addr_valid = addr >= 0 && addr < ARRAY_SIZE(bus->mdio_map);
        struct mdio_device *mdiodev;
  
 -      if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
 +      if (WARN_ONCE(!addr_valid, "addr %d out of range\n", addr))
                return NULL;
  
        mdiodev = bus->mdio_map[addr];
@@@ -513,126 -511,6 +513,126 @@@ static int mdiobus_create_device(struc
        return ret;
  }
  
 +static struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr, bool c45)
 +{
 +      struct phy_device *phydev = ERR_PTR(-ENODEV);
 +      int err;
 +
 +      phydev = get_phy_device(bus, addr, c45);
 +      if (IS_ERR(phydev))
 +              return phydev;
 +
 +      /* For DT, see if the auto-probed phy has a corresponding child
 +       * in the bus node, and set the of_node pointer in this case.
 +       */
 +      of_mdiobus_link_mdiodev(bus, &phydev->mdio);
 +
 +      err = phy_device_register(phydev);
 +      if (err) {
 +              phy_device_free(phydev);
 +              return ERR_PTR(-ENODEV);
 +      }
 +
 +      return phydev;
 +}
 +
 +/**
 + * mdiobus_scan_c22 - scan one address on a bus for C22 MDIO devices.
 + * @bus: mii_bus to scan
 + * @addr: address on bus to scan
 + *
 + * This function scans one address on the MDIO bus, looking for
 + * devices which can be identified using a vendor/product ID in
 + * registers 2 and 3. Not all MDIO devices have such registers, but
 + * PHY devices typically do. Hence this function assumes anything
 + * found is a PHY, or can be treated as a PHY. Other MDIO devices,
 + * such as switches, will probably not be found during the scan.
 + */
 +struct phy_device *mdiobus_scan_c22(struct mii_bus *bus, int addr)
 +{
 +      return mdiobus_scan(bus, addr, false);
 +}
 +EXPORT_SYMBOL(mdiobus_scan_c22);
 +
 +/**
 + * mdiobus_scan_c45 - scan one address on a bus for C45 MDIO devices.
 + * @bus: mii_bus to scan
 + * @addr: address on bus to scan
 + *
 + * This function scans one address on the MDIO bus, looking for
 + * devices which can be identified using a vendor/product ID in
 + * registers 2 and 3. Not all MDIO devices have such registers, but
 + * PHY devices typically do. Hence this function assumes anything
 + * found is a PHY, or can be treated as a PHY. Other MDIO devices,
 + * such as switches, will probably not be found during the scan.
 + */
 +static struct phy_device *mdiobus_scan_c45(struct mii_bus *bus, int addr)
 +{
 +      return mdiobus_scan(bus, addr, true);
 +}
 +
 +static int mdiobus_scan_bus_c22(struct mii_bus *bus)
 +{
 +      int i;
 +
 +      for (i = 0; i < PHY_MAX_ADDR; i++) {
 +              if ((bus->phy_mask & BIT(i)) == 0) {
 +                      struct phy_device *phydev;
 +
 +                      phydev = mdiobus_scan_c22(bus, i);
 +                      if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV))
 +                              return PTR_ERR(phydev);
 +              }
 +      }
 +      return 0;
 +}
 +
 +static int mdiobus_scan_bus_c45(struct mii_bus *bus)
 +{
 +      int i;
 +
 +      for (i = 0; i < PHY_MAX_ADDR; i++) {
 +              if ((bus->phy_mask & BIT(i)) == 0) {
 +                      struct phy_device *phydev;
 +
 +                      /* Don't scan C45 if we already have a C22 device */
 +                      if (bus->mdio_map[i])
 +                              continue;
 +
 +                      phydev = mdiobus_scan_c45(bus, i);
 +                      if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV))
 +                              return PTR_ERR(phydev);
 +              }
 +      }
 +      return 0;
 +}
 +
 +/* There are some C22 PHYs which do bad things when where is a C45
 + * transaction on the bus, like accepting a read themselves, and
 + * stomping over the true devices reply, to performing a write to
 + * themselves which was intended for another device. Now that C22
 + * devices have been found, see if any of them are bad for C45, and if we
 + * should skip the C45 scan.
 + */
 +static bool mdiobus_prevent_c45_scan(struct mii_bus *bus)
 +{
 +      int i;
 +
 +      for (i = 0; i < PHY_MAX_ADDR; i++) {
 +              struct phy_device *phydev;
 +              u32 oui;
 +
 +              phydev = mdiobus_get_phy(bus, i);
 +              if (!phydev)
 +                      continue;
 +              oui = phydev->phy_id >> 10;
 +
 +              if (oui == MICREL_OUI)
 +                      return true;
 +      }
 +      return false;
 +}
 +
  /**
   * __mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
   * @bus: target mii_bus
  int __mdiobus_register(struct mii_bus *bus, struct module *owner)
  {
        struct mdio_device *mdiodev;
 -      int i, err;
        struct gpio_desc *gpiod;
 +      bool prevent_c45_scan;
 +      int i, err;
 +
 +      if (!bus || !bus->name)
 +              return -EINVAL;
  
 -      if (NULL == bus || NULL == bus->name ||
 -          NULL == bus->read || NULL == bus->write)
 +      /* An access method always needs both read and write operations */
 +      if (!!bus->read != !!bus->write || !!bus->read_c45 != !!bus->write_c45)
 +              return -EINVAL;
 +
 +      /* At least one method is mandatory */
 +      if (!bus->read && !bus->read_c45)
                return -EINVAL;
  
        if (bus->parent && bus->parent->of_node)
                        goto error_reset_gpiod;
        }
  
 -      for (i = 0; i < PHY_MAX_ADDR; i++) {
 -              if ((bus->phy_mask & BIT(i)) == 0) {
 -                      struct phy_device *phydev;
 +      if (bus->read) {
 +              err = mdiobus_scan_bus_c22(bus);
 +              if (err)
 +                      goto error;
 +      }
  
 -                      phydev = mdiobus_scan(bus, i);
 -                      if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV)) {
 -                              err = PTR_ERR(phydev);
 -                              goto error;
 -                      }
 -              }
 +      prevent_c45_scan = mdiobus_prevent_c45_scan(bus);
 +
 +      if (!prevent_c45_scan && bus->read_c45) {
 +              err = mdiobus_scan_bus_c45(bus);
 +              if (err)
 +                      goto error;
        }
  
        mdiobus_setup_mdiodev_from_board_info(bus, mdiobus_create_device);
        return 0;
  
  error:
 -      while (--i >= 0) {
 +      for (i = 0; i < PHY_MAX_ADDR; i++) {
                mdiodev = bus->mdio_map[i];
                if (!mdiodev)
                        continue;
@@@ -809,6 -677,57 +809,6 @@@ void mdiobus_free(struct mii_bus *bus
  }
  EXPORT_SYMBOL(mdiobus_free);
  
 -/**
 - * mdiobus_scan - scan a bus for MDIO devices.
 - * @bus: mii_bus to scan
 - * @addr: address on bus to scan
 - *
 - * This function scans the MDIO bus, looking for devices which can be
 - * identified using a vendor/product ID in registers 2 and 3. Not all
 - * MDIO devices have such registers, but PHY devices typically
 - * do. Hence this function assumes anything found is a PHY, or can be
 - * treated as a PHY. Other MDIO devices, such as switches, will
 - * probably not be found during the scan.
 - */
 -struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
 -{
 -      struct phy_device *phydev = ERR_PTR(-ENODEV);
 -      int err;
 -
 -      switch (bus->probe_capabilities) {
 -      case MDIOBUS_NO_CAP:
 -      case MDIOBUS_C22:
 -              phydev = get_phy_device(bus, addr, false);
 -              break;
 -      case MDIOBUS_C45:
 -              phydev = get_phy_device(bus, addr, true);
 -              break;
 -      case MDIOBUS_C22_C45:
 -              phydev = get_phy_device(bus, addr, false);
 -              if (IS_ERR(phydev))
 -                      phydev = get_phy_device(bus, addr, true);
 -              break;
 -      }
 -
 -      if (IS_ERR(phydev))
 -              return phydev;
 -
 -      /*
 -       * For DT, see if the auto-probed phy has a correspoding child
 -       * in the bus node, and set the of_node pointer in this case.
 -       */
 -      of_mdiobus_link_mdiodev(bus, &phydev->mdio);
 -
 -      err = phy_device_register(phydev);
 -      if (err) {
 -              phy_device_free(phydev);
 -              return ERR_PTR(-ENODEV);
 -      }
 -
 -      return phydev;
 -}
 -EXPORT_SYMBOL(mdiobus_scan);
 -
  static void mdiobus_stats_acct(struct mdio_bus_stats *stats, bool op, int ret)
  {
        preempt_disable();
@@@ -845,10 -764,7 +845,10 @@@ int __mdiobus_read(struct mii_bus *bus
  
        lockdep_assert_held_once(&bus->mdio_lock);
  
 -      retval = bus->read(bus, addr, regnum);
 +      if (bus->read)
 +              retval = bus->read(bus, addr, regnum);
 +      else
 +              retval = -EOPNOTSUPP;
  
        trace_mdio_access(bus, 1, addr, regnum, retval, retval);
        mdiobus_stats_acct(&bus->stats[addr], true, retval);
@@@ -874,10 -790,7 +874,10 @@@ int __mdiobus_write(struct mii_bus *bus
  
        lockdep_assert_held_once(&bus->mdio_lock);
  
 -      err = bus->write(bus, addr, regnum, val);
 +      if (bus->write)
 +              err = bus->write(bus, addr, regnum, val);
 +      else
 +              err = -EOPNOTSUPP;
  
        trace_mdio_access(bus, 0, addr, regnum, val, err);
        mdiobus_stats_acct(&bus->stats[addr], false, err);
@@@ -918,99 -831,6 +918,99 @@@ int __mdiobus_modify_changed(struct mii
  }
  EXPORT_SYMBOL_GPL(__mdiobus_modify_changed);
  
 +/**
 + * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to read
 + *
 + * Read a MDIO bus register. Caller must hold the mdio bus lock.
 + *
 + * NOTE: MUST NOT be called from interrupt context.
 + */
 +int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
 +{
 +      int retval;
 +
 +      lockdep_assert_held_once(&bus->mdio_lock);
 +
 +      if (bus->read_c45)
 +              retval = bus->read_c45(bus, addr, devad, regnum);
 +      else
 +              retval = -EOPNOTSUPP;
 +
 +      trace_mdio_access(bus, 1, addr, regnum, retval, retval);
 +      mdiobus_stats_acct(&bus->stats[addr], true, retval);
 +
 +      return retval;
 +}
 +EXPORT_SYMBOL(__mdiobus_c45_read);
 +
 +/**
 + * __mdiobus_c45_write - Unlocked version of the mdiobus_write function
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to write
 + * @val: value to write to @regnum
 + *
 + * Write a MDIO bus register. Caller must hold the mdio bus lock.
 + *
 + * NOTE: MUST NOT be called from interrupt context.
 + */
 +int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
 +                      u16 val)
 +{
 +      int err;
 +
 +      lockdep_assert_held_once(&bus->mdio_lock);
 +
 +      if (bus->write_c45)
 +              err = bus->write_c45(bus, addr, devad, regnum, val);
 +      else
 +              err = -EOPNOTSUPP;
 +
 +      trace_mdio_access(bus, 0, addr, regnum, val, err);
 +      mdiobus_stats_acct(&bus->stats[addr], false, err);
 +
 +      return err;
 +}
 +EXPORT_SYMBOL(__mdiobus_c45_write);
 +
 +/**
 + * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to modify
 + * @mask: bit mask of bits to clear
 + * @set: bit mask of bits to set
 + *
 + * Read, modify, and if any change, write the register value back to the
 + * device. Any error returns a negative number.
 + *
 + * NOTE: MUST NOT be called from interrupt context.
 + */
 +static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr,
 +                                      int devad, u32 regnum, u16 mask,
 +                                      u16 set)
 +{
 +      int new, ret;
 +
 +      ret = __mdiobus_c45_read(bus, addr, devad, regnum);
 +      if (ret < 0)
 +              return ret;
 +
 +      new = (ret & ~mask) | set;
 +      if (new == ret)
 +              return 0;
 +
 +      ret = __mdiobus_c45_write(bus, addr, devad, regnum, new);
 +
 +      return ret < 0 ? ret : 1;
 +}
 +
  /**
   * mdiobus_read_nested - Nested version of the mdiobus_read function
   * @bus: the mii_bus struct
@@@ -1058,56 -878,6 +1058,56 @@@ int mdiobus_read(struct mii_bus *bus, i
  }
  EXPORT_SYMBOL(mdiobus_read);
  
 +/**
 + * mdiobus_c45_read - Convenience function for reading a given MII mgmt register
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to read
 + *
 + * NOTE: MUST NOT be called from interrupt context,
 + * because the bus read/write functions may wait for an interrupt
 + * to conclude the operation.
 + */
 +int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
 +{
 +      int retval;
 +
 +      mutex_lock(&bus->mdio_lock);
 +      retval = __mdiobus_c45_read(bus, addr, devad, regnum);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return retval;
 +}
 +EXPORT_SYMBOL(mdiobus_c45_read);
 +
 +/**
 + * mdiobus_c45_read_nested - Nested version of the mdiobus_c45_read function
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to read
 + *
 + * In case of nested MDIO bus access avoid lockdep false positives by
 + * using mutex_lock_nested().
 + *
 + * NOTE: MUST NOT be called from interrupt context,
 + * because the bus read/write functions may wait for an interrupt
 + * to conclude the operation.
 + */
 +int mdiobus_c45_read_nested(struct mii_bus *bus, int addr, int devad,
 +                          u32 regnum)
 +{
 +      int retval;
 +
 +      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 +      retval = __mdiobus_c45_read(bus, addr, devad, regnum);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return retval;
 +}
 +EXPORT_SYMBOL(mdiobus_c45_read_nested);
 +
  /**
   * mdiobus_write_nested - Nested version of the mdiobus_write function
   * @bus: the mii_bus struct
@@@ -1157,59 -927,6 +1157,59 @@@ int mdiobus_write(struct mii_bus *bus, 
  }
  EXPORT_SYMBOL(mdiobus_write);
  
 +/**
 + * mdiobus_c45_write - Convenience function for writing a given MII mgmt register
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to write
 + * @val: value to write to @regnum
 + *
 + * NOTE: MUST NOT be called from interrupt context,
 + * because the bus read/write functions may wait for an interrupt
 + * to conclude the operation.
 + */
 +int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
 +                    u16 val)
 +{
 +      int err;
 +
 +      mutex_lock(&bus->mdio_lock);
 +      err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return err;
 +}
 +EXPORT_SYMBOL(mdiobus_c45_write);
 +
 +/**
 + * mdiobus_c45_write_nested - Nested version of the mdiobus_c45_write function
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to write
 + * @val: value to write to @regnum
 + *
 + * In case of nested MDIO bus access avoid lockdep false positives by
 + * using mutex_lock_nested().
 + *
 + * NOTE: MUST NOT be called from interrupt context,
 + * because the bus read/write functions may wait for an interrupt
 + * to conclude the operation.
 + */
 +int mdiobus_c45_write_nested(struct mii_bus *bus, int addr, int devad,
 +                           u32 regnum, u16 val)
 +{
 +      int err;
 +
 +      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
 +      err = __mdiobus_c45_write(bus, addr, devad, regnum, val);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return err;
 +}
 +EXPORT_SYMBOL(mdiobus_c45_write_nested);
 +
  /**
   * mdiobus_modify - Convenience function for modifying a given mdio device
   *    register
@@@ -1231,30 -948,6 +1231,30 @@@ int mdiobus_modify(struct mii_bus *bus
  }
  EXPORT_SYMBOL_GPL(mdiobus_modify);
  
 +/**
 + * mdiobus_c45_modify - Convenience function for modifying a given mdio device
 + *    register
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to write
 + * @mask: bit mask of bits to clear
 + * @set: bit mask of bits to set
 + */
 +int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
 +                     u16 mask, u16 set)
 +{
 +      int err;
 +
 +      mutex_lock(&bus->mdio_lock);
 +      err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum,
 +                                         mask, set);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return err < 0 ? err : 0;
 +}
 +EXPORT_SYMBOL_GPL(mdiobus_c45_modify);
 +
  /**
   * mdiobus_modify_changed - Convenience function for modifying a given mdio
   *    device register and returning if it changed
@@@ -1277,29 -970,6 +1277,29 @@@ int mdiobus_modify_changed(struct mii_b
  }
  EXPORT_SYMBOL_GPL(mdiobus_modify_changed);
  
 +/**
 + * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio
 + *    device register and returning if it changed
 + * @bus: the mii_bus struct
 + * @addr: the phy address
 + * @devad: device address to read
 + * @regnum: register number to write
 + * @mask: bit mask of bits to clear
 + * @set: bit mask of bits to set
 + */
 +int mdiobus_c45_modify_changed(struct mii_bus *bus, int devad, int addr,
 +                             u32 regnum, u16 mask, u16 set)
 +{
 +      int err;
 +
 +      mutex_lock(&bus->mdio_lock);
 +      err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set);
 +      mutex_unlock(&bus->mdio_lock);
 +
 +      return err;
 +}
 +EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed);
 +
  /**
   * mdio_bus_match - determine if given MDIO driver supports the given
   *                MDIO device
@@@ -1330,7 -1000,7 +1330,7 @@@ static int mdio_bus_match(struct devic
        return 0;
  }
  
- static int mdio_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int mdio_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
        int rc;
  
diff --combined drivers/nvdimm/nd.h
index ec5219680092d7abcf4ed4bc6911f361a43419ea,cc166f99b0056b7d7b4975c74726d6e984aa405a..e8b9d27dbb3c3457927f2977f8d8e6aebcb4573b
@@@ -599,7 -599,7 +599,7 @@@ static inline int nd_pfn_validate(struc
  struct nd_dax *to_nd_dax(struct device *dev);
  #if IS_ENABLED(CONFIG_NVDIMM_DAX)
  int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns);
- bool is_nd_dax(struct device *dev);
+ bool is_nd_dax(const struct device *dev);
  struct device *nd_dax_create(struct nd_region *nd_region);
  #else
  static inline int nd_dax_probe(struct device *dev,
        return -ENODEV;
  }
  
- static inline bool is_nd_dax(struct device *dev)
+ static inline bool is_nd_dax(const struct device *dev)
  {
        return false;
  }
@@@ -652,7 -652,7 +652,7 @@@ void devm_namespace_disable(struct devi
                struct nd_namespace_common *ndns);
  #if IS_ENABLED(CONFIG_ND_CLAIM)
  /* max struct page size independent of kernel config */
 -#define MAX_STRUCT_PAGE_SIZE 128
 +#define MAX_STRUCT_PAGE_SIZE 64
  int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
  #else
  static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
diff --combined drivers/of/device.c
index 8271793ef379085b0dae5c87a6bbbf6d766b1ac1,dda51b7ce5970dd7f57cd84362cc209cf7c0f8ec..955bfb3d1a834e12a935b98406f9d551b3404b5b
@@@ -248,7 -248,7 +248,7 @@@ const void *of_device_get_match_data(co
  }
  EXPORT_SYMBOL(of_device_get_match_data);
  
- static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
+ static ssize_t of_device_get_modalias(const struct device *dev, char *str, ssize_t len)
  {
        const char *compat;
        char *c;
        ssize_t csize;
        ssize_t tsize;
  
 -      if ((!dev) || (!dev->of_node))
 +      if ((!dev) || (!dev->of_node) || dev->of_node_reused)
                return -ENODEV;
  
        /* Name & Type */
@@@ -372,11 -372,11 +372,11 @@@ void of_device_uevent(const struct devi
        mutex_unlock(&of_mutex);
  }
  
- int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+ int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env)
  {
        int sl;
  
 -      if ((!dev) || (!dev->of_node))
 +      if ((!dev) || (!dev->of_node) || dev->of_node_reused)
                return -ENODEV;
  
        /* Devicetree modalias is tricky, we add it in 2 steps */
  
        sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
                                    sizeof(env->buf) - env->buflen);
 +      if (sl < 0)
 +              return sl;
        if (sl >= (sizeof(env->buf) - env->buflen))
                return -ENOMEM;
        env->buflen += sl;
diff --combined drivers/of/property.c
index 95b838185b2f566c9a446d48e017ce1ba749777c,c651aad6f34b1db3311e230f7ec8993e97d63897..fb210e921ca9452ddf59f1a539968f37cea28ed7
@@@ -1062,20 -1062,6 +1062,6 @@@ of_fwnode_device_get_match_data(const s
        return of_device_get_match_data(dev);
  }
  
- static bool of_is_ancestor_of(struct device_node *test_ancestor,
-                             struct device_node *child)
- {
-       of_node_get(child);
-       while (child) {
-               if (child == test_ancestor) {
-                       of_node_put(child);
-                       return true;
-               }
-               child = of_get_next_parent(child);
-       }
-       return false;
- }
  static struct device_node *of_get_compat_node(struct device_node *np)
  {
        of_node_get(np);
@@@ -1106,71 -1092,27 +1092,27 @@@ static struct device_node *of_get_compa
        return node;
  }
  
- /**
-  * of_link_to_phandle - Add fwnode link to supplier from supplier phandle
-  * @con_np: consumer device tree node
-  * @sup_np: supplier device tree node
-  *
-  * Given a phandle to a supplier device tree node (@sup_np), this function
-  * finds the device that owns the supplier device tree node and creates a
-  * device link from @dev consumer device to the supplier device. This function
-  * doesn't create device links for invalid scenarios such as trying to create a
-  * link with a parent device as the consumer of its child device. In such
-  * cases, it returns an error.
-  *
-  * Returns:
-  * - 0 if fwnode link successfully created to supplier
-  * - -EINVAL if the supplier link is invalid and should not be created
-  * - -ENODEV if struct device will never be create for supplier
-  */
- static int of_link_to_phandle(struct device_node *con_np,
+ static void of_link_to_phandle(struct device_node *con_np,
                              struct device_node *sup_np)
  {
-       struct device *sup_dev;
-       struct device_node *tmp_np = sup_np;
+       struct device_node *tmp_np = of_node_get(sup_np);
  
-       /*
-        * Find the device node that contains the supplier phandle.  It may be
-        * @sup_np or it may be an ancestor of @sup_np.
-        */
-       sup_np = of_get_compat_node(sup_np);
-       if (!sup_np) {
-               pr_debug("Not linking %pOFP to %pOFP - No device\n",
-                        con_np, tmp_np);
-               return -ENODEV;
-       }
+       /* Check that sup_np and its ancestors are available. */
+       while (tmp_np) {
+               if (of_fwnode_handle(tmp_np)->dev) {
+                       of_node_put(tmp_np);
+                       break;
+               }
  
-       /*
-        * Don't allow linking a device node as a consumer of one of its
-        * descendant nodes. By definition, a child node can't be a functional
-        * dependency for the parent node.
-        */
-       if (of_is_ancestor_of(con_np, sup_np)) {
-               pr_debug("Not linking %pOFP to %pOFP - is descendant\n",
-                        con_np, sup_np);
-               of_node_put(sup_np);
-               return -EINVAL;
-       }
+               if (!of_device_is_available(tmp_np)) {
+                       of_node_put(tmp_np);
+                       return;
+               }
  
-       /*
-        * Don't create links to "early devices" that won't have struct devices
-        * created for them.
-        */
-       sup_dev = get_dev_from_fwnode(&sup_np->fwnode);
-       if (!sup_dev &&
-           (of_node_check_flag(sup_np, OF_POPULATED) ||
-            sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) {
-               pr_debug("Not linking %pOFP to %pOFP - No struct device\n",
-                        con_np, sup_np);
-               of_node_put(sup_np);
-               return -ENODEV;
+               tmp_np = of_get_next_parent(tmp_np);
        }
-       put_device(sup_dev);
  
        fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
-       of_node_put(sup_np);
-       return 0;
  }
  
  /**
@@@ -1202,8 -1144,8 +1144,8 @@@ static struct device_node *parse_prop_c
        if (strcmp(prop_name, list_name))
                return NULL;
  
 -      if (of_parse_phandle_with_args(np, list_name, cells_name, index,
 -                                     &sup_args))
 +      if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index,
 +                                       &sup_args))
                return NULL;
  
        return sup_args.np;
@@@ -1307,7 -1249,7 +1249,7 @@@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-
  DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells")
  DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells")
  DEFINE_SIMPLE_PROP(extcon, "extcon", NULL)
 -DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL)
 +DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells")
  DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells")
  DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL)
  DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL)
index 7004eb4a63a28583fbcfb978cadf4af6206b4976,407eb55050a6c80cf5ad34607887cb595856007c..aaad41294200de2d1bca1ec1bf742bf166c3d171
@@@ -35,9 -35,9 +35,9 @@@ static struct attribute *ssam_device_at
  };
  ATTRIBUTE_GROUPS(ssam_device);
  
- static int ssam_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int ssam_device_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct ssam_device *sdev = to_ssam_device(dev);
+       const struct ssam_device *sdev = to_ssam_device(dev);
  
        return add_uevent_var(env, "MODALIAS=ssam:d%02Xc%02Xt%02Xi%02Xf%02X",
                              sdev->uid.domain, sdev->uid.category,
@@@ -136,9 -136,9 +136,9 @@@ int ssam_device_add(struct ssam_device 
         * is always valid and can be used for requests as long as the client
         * device we add here is registered as child under it. This essentially
         * guarantees that the client driver can always expect the preconditions
 -       * for functions like ssam_request_sync (controller has to be started
 -       * and is not suspended) to hold and thus does not have to check for
 -       * them.
 +       * for functions like ssam_request_do_sync() (controller has to be
 +       * started and is not suspended) to hold and thus does not have to check
 +       * for them.
         *
         * Note that for this to work, the controller has to be a parent device.
         * If it is not a direct parent, care has to be taken that the device is
diff --combined drivers/s390/cio/css.c
index dfbb998db86ff3f60063f00562f9dfca46d89691,0723921902da610e5d61944c0c8da69e53a2686d..3ef636935a547c9478dd1079c6c5b8bc9f42ffed
@@@ -740,21 -740,12 +740,21 @@@ void css_schedule_eval_all(void
        spin_unlock_irqrestore(&slow_subchannel_lock, flags);
  }
  
 -static int __unset_registered(struct device *dev, void *data)
 +static int __unset_validpath(struct device *dev, void *data)
  {
        struct idset *set = data;
        struct subchannel *sch = to_subchannel(dev);
 +      struct pmcw *pmcw = &sch->schib.pmcw;
 +
 +      /* Here we want to make sure that we are considering only those subchannels
 +       * which do not have an operational device attached to it. This can be found
 +       * with the help of PAM and POM values of pmcw. OPM provides the information
 +       * about any path which is currently vary-off, so that we should not consider.
 +       */
 +      if (sch->st == SUBCHANNEL_TYPE_IO &&
 +          (sch->opm & pmcw->pam & pmcw->pom))
 +              idset_sch_del(set, sch->schid);
  
 -      idset_sch_del(set, sch->schid);
        return 0;
  }
  
@@@ -783,8 -774,8 +783,8 @@@ void css_schedule_eval_cond(enum css_ev
        }
        idset_fill(set);
        switch (cond) {
 -      case CSS_EVAL_UNREG:
 -              bus_for_each_dev(&css_bus_type, NULL, set, __unset_registered);
 +      case CSS_EVAL_NO_PATH:
 +              bus_for_each_dev(&css_bus_type, NULL, set, __unset_validpath);
                break;
        case CSS_EVAL_NOT_ONLINE:
                bus_for_each_dev(&css_bus_type, NULL, set, __unset_online);
@@@ -807,11 -798,11 +807,11 @@@ void css_wait_for_slow_path(void
        flush_workqueue(cio_work_q);
  }
  
 -/* Schedule reprobing of all unregistered subchannels. */
 +/* Schedule reprobing of all subchannels with no valid operational path. */
  void css_schedule_reprobe(void)
  {
        /* Schedule with a delay to allow merging of subsequent calls. */
 -      css_schedule_eval_cond(CSS_EVAL_UNREG, 1 * HZ);
 +      css_schedule_eval_cond(CSS_EVAL_NO_PATH, 1 * HZ);
  }
  EXPORT_SYMBOL_GPL(css_schedule_reprobe);
  
@@@ -1411,9 -1402,9 +1411,9 @@@ static void css_shutdown(struct device 
                sch->driver->shutdown(sch);
  }
  
- static int css_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int css_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct subchannel *sch = to_subchannel(dev);
+       const struct subchannel *sch = to_subchannel(dev);
        int ret;
  
        ret = add_uevent_var(env, "ST=%01X", sch->st);
index 5418e60dbfc3303c93f5bb86e226d32ca9ab4de7,b07ffd9ff117182bea74ec985d99545f12539298..8eb089b99cde92bad4670656b281b4cfcc8425b6
@@@ -80,7 -80,7 +80,7 @@@ ccw_bus_match (struct device * dev, str
   * specified size. Return length of resulting string (excluding trailing '\0')
   * even if string doesn't fit buffer (snprintf semantics). */
  static int snprint_alias(char *buf, size_t size,
-                        struct ccw_device_id *id, const char *suffix)
+                        const struct ccw_device_id *id, const char *suffix)
  {
        int len;
  
  
  /* Set up environment variables for ccw device uevent. Return 0 on success,
   * non-zero otherwise. */
- static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int ccw_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct ccw_device *cdev = to_ccwdev(dev);
-       struct ccw_device_id *id = &(cdev->id);
+       const struct ccw_device *cdev = to_ccwdev(dev);
+       const struct ccw_device_id *id = &(cdev->id);
        int ret;
        char modalias_buf[30];
  
@@@ -244,13 -244,10 +244,13 @@@ int ccw_device_is_orphan(struct ccw_dev
  
  static void ccw_device_unregister(struct ccw_device *cdev)
  {
 +      mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                /* Undo device_add(). */
                device_del(&cdev->dev);
        }
 +      mutex_unlock(&cdev->reg_mutex);
 +
        if (cdev->private->flags.initialized) {
                cdev->private->flags.initialized = 0;
                /* Release reference from device_initialize(). */
@@@ -656,13 -653,11 +656,13 @@@ static void ccw_device_do_unbind_bind(s
  {
        int ret;
  
 +      mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                device_release_driver(&cdev->dev);
                ret = device_attach(&cdev->dev);
                WARN_ON(ret == -ENODEV);
        }
 +      mutex_unlock(&cdev->reg_mutex);
  }
  
  static void
@@@ -745,7 -740,6 +745,7 @@@ static int io_subchannel_initialize_dev
        INIT_LIST_HEAD(&priv->cmb_list);
        init_waitqueue_head(&priv->wait_q);
        timer_setup(&priv->timer, ccw_device_timeout, 0);
 +      mutex_init(&cdev->reg_mutex);
  
        atomic_set(&priv->onoff, 0);
        cdev->ccwlock = sch->lock;
@@@ -831,7 -825,6 +831,7 @@@ static void io_subchannel_register(stru
         * be registered). We need to reprobe since we may now have sense id
         * information.
         */
 +      mutex_lock(&cdev->reg_mutex);
        if (device_is_registered(&cdev->dev)) {
                if (!cdev->drv) {
                        ret = device_reprobe(&cdev->dev);
                spin_lock_irqsave(sch->lock, flags);
                sch_set_cdev(sch, NULL);
                spin_unlock_irqrestore(sch->lock, flags);
 +              mutex_unlock(&cdev->reg_mutex);
                /* Release initial device reference. */
                put_device(&cdev->dev);
                goto out_err;
        }
  out:
        cdev->private->flags.recog_done = 1;
 +      mutex_unlock(&cdev->reg_mutex);
        wake_up(&cdev->private->wait_q);
  out_err:
        if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
index 8ef9a54943403a8c717ed64bbe44181a6bed1ece,a0dd711eb40827d9800d434dc565fa3b74634575..ee28f73af4d4ff24b5f27bc1a3e17c46be7f4369
@@@ -451,8 -451,6 +451,8 @@@ static void scsi_device_dev_release(str
        struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL;
        unsigned long flags;
  
 +      might_sleep();
 +
        scsi_dh_release_device(sdev);
  
        parent = sdev->sdev_gendev.parent;
@@@ -536,9 -534,9 +536,9 @@@ static int scsi_bus_match(struct devic
        return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
  }
  
- static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int scsi_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct scsi_device *sdev;
+       const struct scsi_device *sdev;
  
        if (dev->type != &scsi_dev_type)
                return 0;
diff --combined drivers/spi/spi.c
index 5866bf5813a4629f77f41267aec442a123fa346e,b85e41a9dc34ef6da6182104a7144a418ab17f29..44b85a8d47f112f795fb0a8a46397daff7999bcf
@@@ -395,7 -395,7 +395,7 @@@ static int spi_match_device(struct devi
        return strcmp(spi->modalias, drv->name) == 0;
  }
  
- static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int spi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
        const struct spi_device         *spi = to_spi_device(dev);
        int rc;
@@@ -604,7 -604,7 +604,7 @@@ static void spi_dev_set_name(struct spi
        }
  
        dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->controller->dev),
 -                   spi->chip_select);
 +                   spi_get_chipselect(spi, 0));
  }
  
  static int spi_dev_check(struct device *dev, void *data)
        struct spi_device *new_spi = data;
  
        if (spi->controller == new_spi->controller &&
 -          spi->chip_select == new_spi->chip_select)
 +          spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0))
                return -EBUSY;
        return 0;
  }
@@@ -638,7 -638,7 +638,7 @@@ static int __spi_add_device(struct spi_
        status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
        if (status) {
                dev_err(dev, "chipselect %d already in use\n",
 -                              spi->chip_select);
 +                              spi_get_chipselect(spi, 0));
                return status;
        }
  
        }
  
        if (ctlr->cs_gpiods)
 -              spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
 +              spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]);
  
        /*
         * Drivers may modify this initial i/o setup, but will
@@@ -692,8 -692,8 +692,8 @@@ int spi_add_device(struct spi_device *s
        int status;
  
        /* Chipselects are numbered 0..max; validate. */
 -      if (spi->chip_select >= ctlr->num_chipselect) {
 -              dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
 +      if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
 +              dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
                        ctlr->num_chipselect);
                return -EINVAL;
        }
@@@ -714,8 -714,8 +714,8 @@@ static int spi_add_device_locked(struc
        struct device *dev = ctlr->dev.parent;
  
        /* Chipselects are numbered 0..max; validate. */
 -      if (spi->chip_select >= ctlr->num_chipselect) {
 -              dev_err(dev, "cs%d >= max %d\n", spi->chip_select,
 +      if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
 +              dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
                        ctlr->num_chipselect);
                return -EINVAL;
        }
@@@ -761,7 -761,7 +761,7 @@@ struct spi_device *spi_new_device(struc
  
        WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
  
 -      proxy->chip_select = chip->chip_select;
 +      spi_set_chipselect(proxy, 0, chip->chip_select);
        proxy->max_speed_hz = chip->max_speed_hz;
        proxy->mode = chip->mode;
        proxy->irq = chip->irq;
@@@ -970,23 -970,24 +970,23 @@@ static void spi_set_cs(struct spi_devic
         * Avoid calling into the driver (or doing delays) if the chip select
         * isn't actually changing from the last time this was called.
         */
 -      if (!force && ((enable && spi->controller->last_cs == spi->chip_select) ||
 -                              (!enable && spi->controller->last_cs != spi->chip_select)) &&
 +      if (!force && ((enable && spi->controller->last_cs == spi_get_chipselect(spi, 0)) ||
 +                     (!enable && spi->controller->last_cs != spi_get_chipselect(spi, 0))) &&
            (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
                return;
  
        trace_spi_set_cs(spi, activate);
  
 -      spi->controller->last_cs = enable ? spi->chip_select : -1;
 +      spi->controller->last_cs = enable ? spi_get_chipselect(spi, 0) : -1;
        spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
  
 -      if ((spi->cs_gpiod || !spi->controller->set_cs_timing) && !activate) {
 +      if ((spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) && !activate)
                spi_delay_exec(&spi->cs_hold, NULL);
 -      }
  
        if (spi->mode & SPI_CS_HIGH)
                enable = !enable;
  
 -      if (spi->cs_gpiod) {
 +      if (spi_get_csgpiod(spi, 0)) {
                if (!(spi->mode & SPI_NO_CS)) {
                        /*
                         * Historically ACPI has no means of the GPIO polarity and
                         * into account.
                         */
                        if (has_acpi_companion(&spi->dev))
 -                              gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
 +                              gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), !enable);
                        else
                                /* Polarity handled by GPIO library */
 -                              gpiod_set_value_cansleep(spi->cs_gpiod, activate);
 +                              gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), activate);
                }
                /* Some SPI masters need both GPIO CS & slave_select */
                if ((spi->controller->flags & SPI_MASTER_GPIO_SS) &&
                spi->controller->set_cs(spi, !enable);
        }
  
 -      if (spi->cs_gpiod || !spi->controller->set_cs_timing) {
 +      if (spi_get_csgpiod(spi, 0) || !spi->controller->set_cs_timing) {
                if (activate)
                        spi_delay_exec(&spi->cs_setup, NULL);
                else
@@@ -1483,13 -1484,6 +1483,13 @@@ static void _spi_transfer_cs_change_del
        }
  }
  
 +void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
 +                                                struct spi_transfer *xfer)
 +{
 +      _spi_transfer_cs_change_delay(msg, xfer);
 +}
 +EXPORT_SYMBOL_GPL(spi_transfer_cs_change_delay_exec);
 +
  /*
   * spi_transfer_one_message - Default implementation of transfer_one_message()
   *
@@@ -1927,7 -1921,7 +1927,7 @@@ void spi_take_timestamp_post(struct spi
        /* Capture the resolution of the timestamp */
        xfer->ptp_sts_word_post = progress;
  
 -      xfer->timestamped = true;
 +      xfer->timestamped = 1;
  }
  EXPORT_SYMBOL_GPL(spi_take_timestamp_post);
  
@@@ -2226,26 -2220,11 +2226,26 @@@ void spi_flush_queue(struct spi_control
  /*-------------------------------------------------------------------------*/
  
  #if defined(CONFIG_OF)
 +static void of_spi_parse_dt_cs_delay(struct device_node *nc,
 +                                   struct spi_delay *delay, const char *prop)
 +{
 +      u32 value;
 +
 +      if (!of_property_read_u32(nc, prop, &value)) {
 +              if (value > U16_MAX) {
 +                      delay->value = DIV_ROUND_UP(value, 1000);
 +                      delay->unit = SPI_DELAY_UNIT_USECS;
 +              } else {
 +                      delay->value = value;
 +                      delay->unit = SPI_DELAY_UNIT_NSECS;
 +              }
 +      }
 +}
 +
  static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
                           struct device_node *nc)
  {
        u32 value;
 -      u16 cs_setup;
        int rc;
  
        /* Mode (clock phase/polarity/etc.) */
                        nc, rc);
                return rc;
        }
 -      spi->chip_select = value;
 +      spi_set_chipselect(spi, 0, value);
  
        /* Device speed */
        if (!of_property_read_u32(nc, "spi-max-frequency", &value))
                spi->max_speed_hz = value;
  
 -      if (!of_property_read_u16(nc, "spi-cs-setup-delay-ns", &cs_setup)) {
 -              spi->cs_setup.value = cs_setup;
 -              spi->cs_setup.unit = SPI_DELAY_UNIT_NSECS;
 -      }
 +      /* Device CS delays */
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns");
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns");
 +      of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns");
  
        return 0;
  }
@@@ -2444,7 -2423,7 +2444,7 @@@ struct spi_device *spi_new_ancillary_de
        strscpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias));
  
        /* Use provided chip-select for ancillary device */
 -      ancillary->chip_select = chip_select;
 +      spi_set_chipselect(ancillary, 0, chip_select);
  
        /* Take over SPI mode/speed from SPI main device */
        ancillary->max_speed_hz = spi->max_speed_hz;
@@@ -2691,7 -2670,7 +2691,7 @@@ struct spi_device *acpi_spi_device_allo
        spi->mode               |= lookup.mode;
        spi->irq                = lookup.irq;
        spi->bits_per_word      = lookup.bits_per_word;
 -      spi->chip_select        = lookup.chip_select;
 +      spi_set_chipselect(spi, 0, lookup.chip_select);
  
        return spi;
  }
@@@ -3072,14 -3051,15 +3072,14 @@@ static int spi_controller_check_ops(str
         * The controller may implement only the high-level SPI-memory like
         * operations if it does not support regular SPI transfers, and this is
         * valid use case.
 -       * If ->mem_ops is NULL, we request that at least one of the
 -       * ->transfer_xxx() method be implemented.
 +       * If ->mem_ops or ->mem_ops->exec_op is NULL, we request that at least
 +       * one of the ->transfer_xxx() method be implemented.
         */
 -      if (ctlr->mem_ops) {
 -              if (!ctlr->mem_ops->exec_op)
 -                      return -EINVAL;
 -      } else if (!ctlr->transfer && !ctlr->transfer_one &&
 +      if (!ctlr->mem_ops || (ctlr->mem_ops && !ctlr->mem_ops->exec_op)) {
 +              if (!ctlr->transfer && !ctlr->transfer_one &&
                   !ctlr->transfer_one_message) {
 -              return -EINVAL;
 +                      return -EINVAL;
 +              }
        }
  
        return 0;
@@@ -3652,7 -3632,7 +3652,7 @@@ static int spi_set_cs_timing(struct spi
        struct device *parent = spi->controller->dev.parent;
        int status = 0;
  
 -      if (spi->controller->set_cs_timing && !spi->cs_gpiod) {
 +      if (spi->controller->set_cs_timing && !spi_get_csgpiod(spi, 0)) {
                if (spi->controller->auto_runtime_pm) {
                        status = pm_runtime_get_sync(parent);
                        if (status < 0) {
@@@ -3857,7 -3837,7 +3857,7 @@@ static int __spi_validate(struct spi_de
         * cs_change is set for each transfer.
         */
        if ((spi->mode & SPI_CS_WORD) && (!(ctlr->mode_bits & SPI_CS_WORD) ||
 -                                        spi->cs_gpiod)) {
 +                                        spi_get_csgpiod(spi, 0))) {
                size_t maxsize;
                int ret;
  
index e1ad1b437291f647f153ed75122b0ffb1fb9203a,cb6c304c445ee58112c4b0c6f4bc24df2277d69f..3370e18ba05f9348c37ec526bbd7641f2673225b
@@@ -513,44 -513,36 +513,44 @@@ int tb_wait_for_port(struct tb_port *po
  
        while (retries--) {
                state = tb_port_state(port);
 -              if (state < 0)
 -                      return state;
 -              if (state == TB_PORT_DISABLED) {
 +              switch (state) {
 +              case TB_PORT_DISABLED:
                        tb_port_dbg(port, "is disabled (state: 0)\n");
                        return 0;
 -              }
 -              if (state == TB_PORT_UNPLUGGED) {
 +
 +              case TB_PORT_UNPLUGGED:
                        if (wait_if_unplugged) {
                                /* used during resume */
                                tb_port_dbg(port,
                                            "is unplugged (state: 7), retrying...\n");
                                msleep(100);
 -                              continue;
 +                              break;
                        }
                        tb_port_dbg(port, "is unplugged (state: 7)\n");
                        return 0;
 -              }
 -              if (state == TB_PORT_UP) {
 -                      tb_port_dbg(port, "is connected, link is up (state: 2)\n");
 +
 +              case TB_PORT_UP:
 +              case TB_PORT_TX_CL0S:
 +              case TB_PORT_RX_CL0S:
 +              case TB_PORT_CL1:
 +              case TB_PORT_CL2:
 +                      tb_port_dbg(port, "is connected, link is up (state: %d)\n", state);
                        return 1;
 +
 +              default:
 +                      if (state < 0)
 +                              return state;
 +
 +                      /*
 +                       * After plug-in the state is TB_PORT_CONNECTING. Give it some
 +                       * time.
 +                       */
 +                      tb_port_dbg(port,
 +                                  "is connected, link is not up (state: %d), retrying...\n",
 +                                  state);
 +                      msleep(100);
                }
  
 -              /*
 -               * After plug-in the state is TB_PORT_CONNECTING. Give it some
 -               * time.
 -               */
 -              tb_port_dbg(port,
 -                          "is connected, link is not up (state: %d), retrying...\n",
 -                          state);
 -              msleep(100);
        }
        tb_port_warn(port,
                     "failed to reach state TB_PORT_UP. Ignoring port...\n");
@@@ -2184,9 -2176,9 +2184,9 @@@ static void tb_switch_release(struct de
        kfree(sw);
  }
  
- static int tb_switch_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int tb_switch_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct tb_switch *sw = tb_to_switch(dev);
+       const struct tb_switch *sw = tb_to_switch(dev);
        const char *type;
  
        if (sw->config.thunderbolt_version == USB4_VERSION_1_0) {
diff --combined drivers/thunderbolt/tb.h
index 2953cf38c29ed50181fa8b6b771c17eb5a3335e9,909da0a98134e53bb4974905af81e1f971040778..cbb20a2773462ab892c2e4e242becbe3085dc0bf
@@@ -223,23 -223,6 +223,23 @@@ struct tb_switch 
        enum tb_clx clx;
  };
  
 +/**
 + * struct tb_bandwidth_group - Bandwidth management group
 + * @tb: Pointer to the domain the group belongs to
 + * @index: Index of the group (aka Group_ID). Valid values %1-%7
 + * @ports: DP IN adapters belonging to this group are linked here
 + *
 + * Any tunnel that requires isochronous bandwidth (that's DP for now) is
 + * attached to a bandwidth group. All tunnels going through the same
 + * USB4 links share the same group and can dynamically distribute the
 + * bandwidth within the group.
 + */
 +struct tb_bandwidth_group {
 +      struct tb *tb;
 +      int index;
 +      struct list_head ports;
 +};
 +
  /**
   * struct tb_port - a thunderbolt port, part of a tb_switch
   * @config: Cached port configuration read from registers
   * @ctl_credits: Buffers reserved for control path
   * @dma_credits: Number of credits allocated for DMA tunneling for all
   *             DMA paths through this port.
 + * @group: Bandwidth allocation group the adapter is assigned to. Only
 + *       used for DP IN adapters for now.
 + * @group_list: The adapter is linked to the group's list of ports through this
   *
   * In USB4 terminology this structure represents an adapter (protocol or
   * lane adapter).
@@@ -292,8 -272,6 +292,8 @@@ struct tb_port 
        unsigned int total_credits;
        unsigned int ctl_credits;
        unsigned int dma_credits;
 +      struct tb_bandwidth_group *group;
 +      struct list_head group_list;
  };
  
  /**
@@@ -837,7 -815,7 +837,7 @@@ static inline bool tb_is_switch(const s
        return dev->type == &tb_switch_type;
  }
  
- static inline struct tb_switch *tb_to_switch(struct device *dev)
+ static inline struct tb_switch *tb_to_switch(const struct device *dev)
  {
        if (tb_is_switch(dev))
                return container_of(dev, struct tb_switch, dev);
@@@ -1069,7 -1047,7 +1069,7 @@@ void tb_port_lane_bonding_disable(struc
  int tb_port_wait_for_link_width(struct tb_port *port, int width,
                                int timeout_msec);
  int tb_port_update_credits(struct tb_port *port);
 -bool tb_port_is_clx_enabled(struct tb_port *port, enum tb_clx clx);
 +bool tb_port_is_clx_enabled(struct tb_port *port, unsigned int clx);
  
  int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
  int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap);
@@@ -1260,21 -1238,6 +1260,21 @@@ int usb4_usb3_port_allocate_bandwidth(s
  int usb4_usb3_port_release_bandwidth(struct tb_port *port, int *upstream_bw,
                                     int *downstream_bw);
  
 +int usb4_dp_port_set_cm_id(struct tb_port *port, int cm_id);
 +bool usb4_dp_port_bw_mode_supported(struct tb_port *port);
 +bool usb4_dp_port_bw_mode_enabled(struct tb_port *port);
 +int usb4_dp_port_set_cm_bw_mode_supported(struct tb_port *port, bool supported);
 +int usb4_dp_port_group_id(struct tb_port *port);
 +int usb4_dp_port_set_group_id(struct tb_port *port, int group_id);
 +int usb4_dp_port_nrd(struct tb_port *port, int *rate, int *lanes);
 +int usb4_dp_port_set_nrd(struct tb_port *port, int rate, int lanes);
 +int usb4_dp_port_granularity(struct tb_port *port);
 +int usb4_dp_port_set_granularity(struct tb_port *port, int granularity);
 +int usb4_dp_port_set_estimated_bw(struct tb_port *port, int bw);
 +int usb4_dp_port_allocated_bw(struct tb_port *port);
 +int usb4_dp_port_allocate_bw(struct tb_port *port, int bw);
 +int usb4_dp_port_requested_bw(struct tb_port *port);
 +
  static inline bool tb_is_usb4_port_device(const struct device *dev)
  {
        return dev->type == &usb4_port_device_type;
index 38703781ee2d1a72a46dfe45ca65d1b56d9e6417,67b780b256a9ec53c2c5126d9eeb75a57c113f31..a98b2108376ae26aadc38b3e011b16aefe302361
@@@ -55,9 -55,9 +55,9 @@@ static int ulpi_match(struct device *de
        return 0;
  }
  
- static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int ulpi_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct ulpi *ulpi = to_ulpi_dev(dev);
+       const struct ulpi *ulpi = to_ulpi_dev(dev);
        int ret;
  
        ret = of_device_uevent_modalias(dev, env);
@@@ -271,7 -271,7 +271,7 @@@ static int ulpi_regs_show(struct seq_fi
  }
  DEFINE_SHOW_ATTRIBUTE(ulpi_regs);
  
 -#define ULPI_ROOT debugfs_lookup(KBUILD_MODNAME, NULL)
 +static struct dentry *ulpi_root;
  
  static int ulpi_register(struct device *dev, struct ulpi *ulpi)
  {
                return ret;
        }
  
 -      root = debugfs_create_dir(dev_name(dev), ULPI_ROOT);
 +      root = debugfs_create_dir(dev_name(dev), ulpi_root);
        debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops);
  
        dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
@@@ -349,7 -349,8 +349,7 @@@ EXPORT_SYMBOL_GPL(ulpi_register_interfa
   */
  void ulpi_unregister_interface(struct ulpi *ulpi)
  {
 -      debugfs_remove_recursive(debugfs_lookup(dev_name(&ulpi->dev),
 -                                              ULPI_ROOT));
 +      debugfs_lookup_and_remove(dev_name(&ulpi->dev), ulpi_root);
        device_unregister(&ulpi->dev);
  }
  EXPORT_SYMBOL_GPL(ulpi_unregister_interface);
  static int __init ulpi_init(void)
  {
        int ret;
 -      struct dentry *root;
  
 -      root = debugfs_create_dir(KBUILD_MODNAME, NULL);
 +      ulpi_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
        ret = bus_register(&ulpi_bus);
        if (ret)
 -              debugfs_remove(root);
 +              debugfs_remove(ulpi_root);
        return ret;
  }
  subsys_initcall(ulpi_init);
  static void __exit ulpi_exit(void)
  {
        bus_unregister(&ulpi_bus);
 -      debugfs_remove_recursive(ULPI_ROOT);
 +      debugfs_remove(ulpi_root);
  }
  module_exit(ulpi_exit);
  
diff --combined drivers/usb/core/usb.c
index a415206cab043c6e17065416875a5e0166f9a119,4df26f4f76e60431cec9770370781ecc8b5ff546..34742fbbd84d3d3fcdc1362befce683748d7999a
@@@ -423,9 -423,9 +423,9 @@@ static void usb_release_dev(struct devi
        kfree(udev);
  }
  
- static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int usb_dev_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct usb_device *usb_dev;
+       const struct usb_device *usb_dev;
  
        usb_dev = to_usb_device(dev);
  
@@@ -505,10 -505,10 +505,10 @@@ static const struct dev_pm_ops usb_devi
  #endif        /* CONFIG_PM */
  
  
- static char *usb_devnode(struct device *dev,
+ static char *usb_devnode(const struct device *dev,
                         umode_t *mode, kuid_t *uid, kgid_t *gid)
  {
-       struct usb_device *usb_dev;
+       const struct usb_device *usb_dev;
  
        usb_dev = to_usb_device(dev);
        return kasprintf(GFP_KERNEL, "bus/usb/%03d/%03d",
@@@ -998,7 -998,7 +998,7 @@@ static void usb_debugfs_init(void
  
  static void usb_debugfs_cleanup(void)
  {
 -      debugfs_remove(debugfs_lookup("devices", usb_debug_root));
 +      debugfs_lookup_and_remove("devices", usb_debug_root);
  }
  
  /*
diff --combined drivers/usb/typec/bus.c
index 0c8d554240be7796593484befa70818f82e9758f,dbcb96151558ccc662c9ae5ccad199393c3353a8..098f0efaa58d18a764cdbd35f75cf3da83b2b258
  #include "bus.h"
  #include "class.h"
  #include "mux.h"
 +#include "retimer.h"
 +
 +static inline int
 +typec_altmode_set_retimer(struct altmode *alt, unsigned long conf, void *data)
 +{
 +      struct typec_retimer_state state;
 +
 +      if (!alt->retimer)
 +              return 0;
 +
 +      state.alt = &alt->adev;
 +      state.mode = conf;
 +      state.data = data;
 +
 +      return typec_retimer_set(alt->retimer, &state);
 +}
  
  static inline int
  typec_altmode_set_mux(struct altmode *alt, unsigned long conf, void *data)
        return typec_mux_set(alt->mux, &state);
  }
  
 +/* Wrapper to set various Type-C port switches together. */
 +static inline int
 +typec_altmode_set_switches(struct altmode *alt, unsigned long conf, void *data)
 +{
 +      int ret;
 +
 +      ret = typec_altmode_set_retimer(alt, conf, data);
 +      if (ret)
 +              return ret;
 +
 +      return typec_altmode_set_mux(alt, conf, data);
 +}
 +
  static int typec_altmode_set_state(struct typec_altmode *adev,
                                   unsigned long conf, void *data)
  {
@@@ -64,7 -35,7 +64,7 @@@
  
        port_altmode = is_port ? to_altmode(adev) : to_altmode(adev)->partner;
  
 -      return typec_altmode_set_mux(port_altmode, conf, data);
 +      return typec_altmode_set_switches(port_altmode, conf, data);
  }
  
  /* -------------------------------------------------------------------------- */
@@@ -102,7 -73,7 +102,7 @@@ int typec_altmode_notify(struct typec_a
        is_port = is_typec_port(adev->dev.parent);
        partner = altmode->partner;
  
 -      ret = typec_altmode_set_mux(is_port ? altmode : partner, conf, data);
 +      ret = typec_altmode_set_switches(is_port ? altmode : partner, conf, data);
        if (ret)
                return ret;
  
@@@ -350,9 -321,9 +350,9 @@@ static int typec_match(struct device *d
        return 0;
  }
  
- static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
-       struct typec_altmode *altmode = to_typec_altmode(dev);
+       const struct typec_altmode *altmode = to_typec_altmode(dev);
  
        if (add_uevent_var(env, "SVID=%04X", altmode->svid))
                return -ENOMEM;
index ed3d070b1ca4e56958a7c1511dce458100a93e2c,a89d8fd3f46ca4ccd56263527c8cea5293effdfb..cc3182f706730430c4aebf3601043692d18e3b0b
@@@ -583,7 -583,6 +583,7 @@@ void typec_unregister_altmode(struct ty
  {
        if (IS_ERR_OR_NULL(adev))
                return;
 +      typec_retimer_put(to_altmode(adev)->retimer);
        typec_mux_put(to_altmode(adev)->mux);
        device_unregister(&adev->dev);
  }
@@@ -1738,7 -1737,7 +1738,7 @@@ static const struct attribute_group *ty
        NULL
  };
  
- static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
+ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
  {
        int ret;
  
@@@ -2109,26 -2108,16 +2109,26 @@@ typec_port_register_altmode(struct type
  {
        struct typec_altmode *adev;
        struct typec_mux *mux;
 +      struct typec_retimer *retimer;
  
        mux = typec_mux_get(&port->dev, desc);
        if (IS_ERR(mux))
                return ERR_CAST(mux);
  
 +      retimer = typec_retimer_get(&port->dev);
 +      if (IS_ERR(retimer)) {
 +              typec_mux_put(mux);
 +              return ERR_CAST(retimer);
 +      }
 +
        adev = typec_register_altmode(&port->dev, desc);
 -      if (IS_ERR(adev))
 +      if (IS_ERR(adev)) {
 +              typec_retimer_put(retimer);
                typec_mux_put(mux);
 -      else
 +      } else {
                to_altmode(adev)->mux = mux;
 +              to_altmode(adev)->retimer = retimer;
 +      }
  
        return adev;
  }
index dcb00938de61e95e6b6e67249e93a81a620e7748,8bf19bca5d3d538f8552905a3bc8dc208396eb42..1f5219e12cc36a5094390ae3a1a7c30211bd42fd
@@@ -14,7 -14,6 +14,7 @@@
  #include <net/inet_common.h>
  #include <net/inet_connection_sock.h>
  #include <net/request_sock.h>
 +#include <trace/events/sock.h>
  
  #include <xen/events.h>
  #include <xen/grant_table.h>
@@@ -174,8 -173,6 +174,8 @@@ static bool pvcalls_conn_back_write(str
        RING_IDX cons, prod, size, array_size;
        int ret;
  
 +      atomic_set(&map->write, 0);
 +
        cons = intf->out_cons;
        prod = intf->out_prod;
        /* read the indexes before dealing with the data */
                iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, vec, 2, size);
        }
  
 -      atomic_set(&map->write, 0);
        ret = inet_sendmsg(map->sock, &msg, size);
        if (ret == -EAGAIN) {
                atomic_inc(&map->write);
@@@ -302,8 -300,6 +302,8 @@@ static void pvcalls_sk_data_ready(struc
        struct sock_mapping *map = sock->sk_user_data;
        struct pvcalls_ioworker *iow;
  
 +      trace_sk_data_ready(sock);
 +
        if (map == NULL)
                return;
  
@@@ -592,8 -588,6 +592,8 @@@ static void pvcalls_pass_sk_data_ready(
        unsigned long flags;
        int notify;
  
 +      trace_sk_data_ready(sock);
 +
        if (mappass == NULL)
                return;
  
@@@ -1191,7 -1185,7 +1191,7 @@@ static void pvcalls_back_remove(struct 
  {
  }
  
- static int pvcalls_back_uevent(struct xenbus_device *xdev,
+ static int pvcalls_back_uevent(const struct xenbus_device *xdev,
                               struct kobj_uevent_env *env)
  {
        return 0;
diff --combined fs/debugfs/inode.c
index bf397f6a6a33f4525d53c996ebfee6e03cdf192b,a7a6a0821605a8725be3ceb3470d192e710f2e73..3f81f73c241a42fca6e0ee8c5d9a393e97673b7e
@@@ -42,7 -42,7 +42,7 @@@ static unsigned int debugfs_allow __ro_
   * so that we can use the file mode as part of a heuristic to determine whether
   * to lock down individual files.
   */
 -static int debugfs_setattr(struct user_namespace *mnt_userns,
 +static int debugfs_setattr(struct mnt_idmap *idmap,
                           struct dentry *dentry, struct iattr *ia)
  {
        int ret;
@@@ -52,7 -52,7 +52,7 @@@
                if (ret)
                        return ret;
        }
 -      return simple_setattr(&init_user_ns, dentry, ia);
 +      return simple_setattr(&nop_mnt_idmap, dentry, ia);
  }
  
  static const struct inode_operations debugfs_file_inode_operations = {
@@@ -802,8 -802,8 +802,8 @@@ EXPORT_SYMBOL_GPL(debugfs_lookup_and_re
   * exist for rename to succeed.
   *
   * This function will return a pointer to old_dentry (which is updated to
-  * reflect renaming) if it succeeds. If an error occurs, %NULL will be
-  * returned.
+  * reflect renaming) if it succeeds. If an error occurs, ERR_PTR(-ERROR)
+  * will be returned.
   *
   * If debugfs is not enabled in the kernel, the value -%ENODEV will be
   * returned.
@@@ -837,7 -837,7 +837,7 @@@ struct dentry *debugfs_rename(struct de
  
        take_dentry_name_snapshot(&old_name, old_dentry);
  
 -      error = simple_rename(&init_user_ns, d_inode(old_dir), old_dentry,
 +      error = simple_rename(&nop_mnt_idmap, d_inode(old_dir), old_dentry,
                              d_inode(new_dir), dentry, 0);
        if (error) {
                release_dentry_name_snapshot(&old_name);
diff --combined fs/dlm/lockspace.c
index 9f344d76afa3a3e95e3a988777a6d80930d920fa,9b6cfc4c30e3d530ec28366ecdf7e7111c8d7e4c..7325acbd1af78b62e6f0224107dd866f7d9ee600
@@@ -215,9 -215,9 +215,9 @@@ static int do_uevent(struct dlm_ls *ls
        return ls->ls_uevent_result;
  }
  
- static int dlm_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
+ static int dlm_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
  {
-       struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
+       const struct dlm_ls *ls = container_of(kobj, struct dlm_ls, ls_kobj);
  
        add_uevent_var(env, "LOCKSPACE=%s", ls->ls_name);
        return 0;
@@@ -381,23 -381,23 +381,23 @@@ static int threads_start(void
  {
        int error;
  
 -      error = dlm_scand_start();
 +      /* Thread for sending/receiving messages for all lockspace's */
 +      error = dlm_midcomms_start();
        if (error) {
 -              log_print("cannot start dlm_scand thread %d", error);
 +              log_print("cannot start dlm midcomms %d", error);
                goto fail;
        }
  
 -      /* Thread for sending/receiving messages for all lockspace's */
 -      error = dlm_midcomms_start();
 +      error = dlm_scand_start();
        if (error) {
 -              log_print("cannot start dlm midcomms %d", error);
 -              goto scand_fail;
 +              log_print("cannot start dlm_scand thread %d", error);
 +              goto midcomms_fail;
        }
  
        return 0;
  
 - scand_fail:
 -      dlm_scand_stop();
 + midcomms_fail:
 +      dlm_midcomms_stop();
   fail:
        return error;
  }
@@@ -572,7 -572,7 +572,7 @@@ static int new_lockspace(const char *na
        spin_lock_init(&ls->ls_rcom_spin);
        get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t));
        ls->ls_recover_status = 0;
 -      ls->ls_recover_seq = 0;
 +      ls->ls_recover_seq = get_random_u64();
        ls->ls_recover_args = NULL;
        init_rwsem(&ls->ls_in_recovery);
        init_rwsem(&ls->ls_recv_active);
@@@ -820,9 -820,6 +820,9 @@@ static int release_lockspace(struct dlm
                return rv;
        }
  
 +      if (ls_count == 1)
 +              dlm_midcomms_version_wait();
 +
        dlm_device_deregister(ls);
  
        if (force < 3 && dlm_user_daemon_available())
diff --combined fs/gfs2/sys.c
index c40118ea4bbcc0a5c391bd3d15ec341cce44b7a6,d8dfabb0bc1262c37e606119454907999232055e..454dc2ff8b5e2815d2e7d7c9ac9001655212dcbd
@@@ -87,7 -87,6 +87,7 @@@ static ssize_t status_show(struct gfs2_
                     "Withdraw In Prog:         %d\n"
                     "Remote Withdraw:          %d\n"
                     "Withdraw Recovery:        %d\n"
 +                   "Deactivating:             %d\n"
                     "sd_log_error:             %d\n"
                     "sd_log_flush_lock:        %d\n"
                     "sd_log_num_revoke:        %u\n"
                     test_bit(SDF_WITHDRAW_IN_PROG, &f),
                     test_bit(SDF_REMOTE_WITHDRAW, &f),
                     test_bit(SDF_WITHDRAW_RECOVERY, &f),
 +                   test_bit(SDF_DEACTIVATING, &f),
                     sdp->sd_log_error,
                     rwsem_is_locked(&sdp->sd_log_flush_lock),
                     sdp->sd_log_num_revoke,
@@@ -769,10 -767,10 +769,10 @@@ void gfs2_sys_fs_del(struct gfs2_sbd *s
        wait_for_completion(&sdp->sd_kobj_unregister);
  }
  
- static int gfs2_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
+ static int gfs2_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
  {
-       struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
-       struct super_block *s = sdp->sd_vfs;
+       const struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
+       const struct super_block *s = sdp->sd_vfs;
  
        add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
        add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
diff --combined fs/kernfs/dir.c
index e3181c3e198866cf81f649daf1c019c1866ab97b,7b13b1c3424c7a5df4aeeba379a153ae7dd12ec5..ef00b5fe8ceea9d9dd3c16a76d89c151dec282fd
@@@ -149,9 -149,6 +149,6 @@@ static int kernfs_path_from_node_locked
        if (kn_from == kn_to)
                return strlcpy(buf, "/", buflen);
  
-       if (!buf)
-               return -EINVAL;
        common = kernfs_common_ancestor(kn_from, kn_to);
        if (WARN_ON(!common))
                return -EINVAL;
@@@ -1200,7 -1197,7 +1197,7 @@@ static struct dentry *kernfs_iop_lookup
        return d_splice_alias(inode, dentry);
  }
  
 -static int kernfs_iop_mkdir(struct user_namespace *mnt_userns,
 +static int kernfs_iop_mkdir(struct mnt_idmap *idmap,
                            struct inode *dir, struct dentry *dentry,
                            umode_t mode)
  {
@@@ -1238,7 -1235,7 +1235,7 @@@ static int kernfs_iop_rmdir(struct inod
        return ret;
  }
  
 -static int kernfs_iop_rename(struct user_namespace *mnt_userns,
 +static int kernfs_iop_rename(struct mnt_idmap *idmap,
                             struct inode *old_dir, struct dentry *old_dentry,
                             struct inode *new_dir, struct dentry *new_dentry,
                             unsigned int flags)
index 16f30975b22b47829ffa4483e4a00411ab08d62a,56a6557b2f4c1485d659f2daaf96282fe0ced043..c9df0407980c9413ce2e8365e5c7e36a3a57a404
@@@ -197,10 -197,7 +197,7 @@@ struct mipi_dsi_device 
  
  #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
  
- static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev)
- {
-       return container_of(dev, struct mipi_dsi_device, dev);
- }
+ #define to_mipi_dsi_device(__dev)     container_of_const(__dev, struct mipi_dsi_device, dev)
  
  /**
   * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
@@@ -296,28 -293,6 +293,28 @@@ int mipi_dsi_dcs_set_display_brightness
                                        u16 brightness);
  int mipi_dsi_dcs_get_display_brightness(struct mipi_dsi_device *dsi,
                                        u16 *brightness);
 +int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
 +                                           u16 brightness);
 +int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 +                                           u16 *brightness);
 +
 +/**
 + * mipi_dsi_generic_write_seq - transmit data using a generic write packet
 + * @dsi: DSI peripheral device
 + * @seq: buffer containing the payload
 + */
 +#define mipi_dsi_generic_write_seq(dsi, seq...)                                \
 +      do {                                                                   \
 +              static const u8 d[] = { seq };                                 \
 +              struct device *dev = &dsi->dev;                                \
 +              int ret;                                                       \
 +              ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));           \
 +              if (ret < 0) {                                                 \
 +                      dev_err_ratelimited(dev, "transmit data failed: %d\n", \
 +                                          ret);                              \
 +                      return ret;                                            \
 +              }                                                              \
 +      } while (0)
  
  /**
   * mipi_dsi_dcs_write_seq - transmit a DCS command with payload
   * @cmd: Command
   * @seq: buffer containing data to be transmitted
   */
 -#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) do {                         \
 -              static const u8 d[] = { cmd, seq };                             \
 -              struct device *dev = &dsi->dev; \
 -              int ret;                                                \
 -              ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
 -              if (ret < 0) {                                          \
 -                      dev_err_ratelimited(dev, "sending command %#02x failed: %d\n", cmd, ret); \
 -                      return ret;                                             \
 -              }                                               \
 +#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)                           \
 +      do {                                                               \
 +              static const u8 d[] = { cmd, seq };                        \
 +              struct device *dev = &dsi->dev;                            \
 +              int ret;                                                   \
 +              ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d));    \
 +              if (ret < 0) {                                             \
 +                      dev_err_ratelimited(                               \
 +                              dev, "sending command %#02x failed: %d\n", \
 +                              cmd, ret);                                 \
 +                      return ret;                                        \
 +              }                                                          \
        } while (0)
  
  /**
diff --combined include/linux/acpi.h
index 4b12dad5a8a4b00f739e02818005e5fdc1e900e1,564b62f13bd0bcc664d23e7797ee343b2bc95cb9..efff750f326d6532844c06e9dc32e925f5deb3bf
@@@ -723,7 -723,7 +723,7 @@@ const struct acpi_device_id *acpi_match
  const void *acpi_device_get_match_data(const struct device *dev);
  extern bool acpi_driver_match_device(struct device *dev,
                                     const struct device_driver *drv);
- int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
+ int acpi_device_uevent_modalias(const struct device *, struct kobj_uevent_env *);
  int acpi_device_modalias(struct device *, char *, int);
  
  struct platform_device *acpi_create_platform_device(struct acpi_device *,
@@@ -950,12 -950,6 +950,12 @@@ static inline bool acpi_driver_match_de
        return false;
  }
  
 +static inline bool acpi_check_dsm(acpi_handle handle, const guid_t *guid,
 +                                u64 rev, u64 funcs)
 +{
 +      return false;
 +}
 +
  static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
                                                   const guid_t *guid,
                                                   u64 rev, u64 func,
        return NULL;
  }
  
- static inline int acpi_device_uevent_modalias(struct device *dev,
 +static inline union acpi_object *acpi_evaluate_dsm_typed(acpi_handle handle,
 +                                                       const guid_t *guid,
 +                                                       u64 rev, u64 func,
 +                                                       union acpi_object *argv4,
 +                                                       acpi_object_type type)
 +{
 +      return NULL;
 +}
 +
+ static inline int acpi_device_uevent_modalias(const struct device *dev,
                                struct kobj_uevent_env *env)
  {
        return -ENODEV;
diff --combined include/linux/firewire.h
index 56505436d1590ca7d043bf80238681742cc86cd0,03ac31ada5e60dbb7be81e3b0ee2c39102b0a410..1716c01c4e5410f26a4d9d5180cc59ccfb50cd3c
@@@ -208,10 -208,7 +208,7 @@@ struct fw_device 
        struct fw_attribute_group attribute_group;
  };
  
- static inline struct fw_device *fw_device(struct device *dev)
- {
-       return container_of(dev, struct fw_device, device);
- }
+ #define fw_device(dev)        container_of_const(dev, struct fw_device, device)
  
  static inline int fw_device_is_shutdown(struct fw_device *device)
  {
@@@ -229,10 -226,7 +226,7 @@@ struct fw_unit 
        struct fw_attribute_group attribute_group;
  };
  
- static inline struct fw_unit *fw_unit(struct device *dev)
- {
-       return container_of(dev, struct fw_unit, device);
- }
+ #define fw_unit(dev)  container_of_const(dev, struct fw_unit, device)
  
  static inline struct fw_unit *fw_unit_get(struct fw_unit *unit)
  {
@@@ -246,10 -240,7 +240,7 @@@ static inline void fw_unit_put(struct f
        put_device(&unit->device);
  }
  
- static inline struct fw_device *fw_parent_device(struct fw_unit *unit)
- {
-       return fw_device(unit->device.parent);
- }
+ #define fw_parent_device(unit)        fw_device(unit->device.parent)
  
  struct ieee1394_device_id;
  
@@@ -278,8 -269,9 +269,8 @@@ typedef void (*fw_transaction_callback_
   * Otherwise there is a danger of recursion of inbound and outbound
   * transactions from and to the local node.
   *
 - * The callback is responsible that either fw_send_response() or kfree()
 - * is called on the @request, except for FCP registers for which the core
 - * takes care of that.
 + * The callback is responsible that fw_send_response() is called on the @request, except for FCP
 + * registers for which the core takes care of that.
   */
  typedef void (*fw_address_callback_t)(struct fw_card *card,
                                      struct fw_request *request,
diff --combined include/linux/hyperv.h
index cd5cb9f6fae04599538cdc41a90bf6340df06d3e,8430e27f3c3fa780f020e2298fbe4592ee3a4d75..bfbc37ce223b03f3f138556104ec4fb871b57e28
@@@ -1273,7 -1273,7 +1273,7 @@@ struct hv_driver 
        } dynids;
  
        int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
 -      int (*remove)(struct hv_device *);
 +      void (*remove)(struct hv_device *dev);
        void (*shutdown)(struct hv_device *);
  
        int (*suspend)(struct hv_device *);
@@@ -1309,10 -1309,7 +1309,7 @@@ struct hv_device 
  };
  
  
- static inline struct hv_device *device_to_hv_device(struct device *d)
- {
-       return container_of(d, struct hv_device, device);
- }
+ #define device_to_hv_device(d)        container_of_const(d, struct hv_device, device)
  
  static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
  {
diff --combined include/linux/spi/spi.h
index a08c20bd833b2f0974c87c3eff3243770ea8bf76,2edf7f09239eec02233f801f5b4b291801ade4fd..4fa26b9a357255f972eb9ededaa958ae258f2f20
@@@ -26,7 -26,6 +26,7 @@@ struct spi_controller
  struct spi_transfer;
  struct spi_controller_mem_ops;
  struct spi_controller_mem_caps;
 +struct spi_message;
  
  /*
   * INTERFACES between SPI master-side drivers and SPI slave protocol handlers,
@@@ -120,8 -119,6 +120,8 @@@ struct spi_delay 
  
  extern int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer);
  extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
 +extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
 +                                                struct spi_transfer *xfer);
  
  /**
   * struct spi_device - Controller side proxy for an SPI slave device
@@@ -226,7 -223,7 +226,7 @@@ struct spi_device 
  static_assert((SPI_MODE_KERNEL_MASK & SPI_MODE_USER_MASK) == 0,
              "SPI_MODE_USER_MASK & SPI_MODE_KERNEL_MASK must not overlap");
  
- static inline struct spi_device *to_spi_device(struct device *dev)
+ static inline struct spi_device *to_spi_device(const struct device *dev)
  {
        return dev ? container_of(dev, struct spi_device, dev) : NULL;
  }
@@@ -266,25 -263,7 +266,25 @@@ static inline void *spi_get_drvdata(str
        return dev_get_drvdata(&spi->dev);
  }
  
 -struct spi_message;
 +static inline u8 spi_get_chipselect(struct spi_device *spi, u8 idx)
 +{
 +      return spi->chip_select;
 +}
 +
 +static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect)
 +{
 +      spi->chip_select = chipselect;
 +}
 +
 +static inline struct gpio_desc *spi_get_csgpiod(struct spi_device *spi, u8 idx)
 +{
 +      return spi->cs_gpiod;
 +}
 +
 +static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod)
 +{
 +      spi->cs_gpiod = csgpiod;
 +}
  
  /**
   * struct spi_driver - Host side "protocol" driver
@@@ -1022,9 -1001,6 +1022,9 @@@ struct spi_transfer 
        void            *rx_buf;
        unsigned        len;
  
 +#define SPI_TRANS_FAIL_NO_START       BIT(0)
 +      u16             error;
 +
        dma_addr_t      tx_dma;
        dma_addr_t      rx_dma;
        struct sg_table tx_sg;
        unsigned        cs_change:1;
        unsigned        tx_nbits:3;
        unsigned        rx_nbits:3;
 +      unsigned        timestamped:1;
  #define       SPI_NBITS_SINGLE        0x01 /* 1bit transfer */
  #define       SPI_NBITS_DUAL          0x02 /* 2bits transfer */
  #define       SPI_NBITS_QUAD          0x04 /* 4bits transfer */
  
        struct ptp_system_timestamp *ptp_sts;
  
 -      bool            timestamped;
 -
        struct list_head transfer_list;
 -
 -#define SPI_TRANS_FAIL_NO_START       BIT(0)
 -      u16             error;
  };
  
  /**
index 1545e5567b152215f1920550e877aa7b06360c54,24151a0e2c96e35d2f188c659e694443fd41468c..df81043b9e71839563792dbbcc322f4ecfb374e7
@@@ -68,9 -68,9 +68,9 @@@ struct ssam_device_uid 
   * match_flags member of the device ID structure. Do not use them directly
   * with struct ssam_device_id or struct ssam_device_uid.
   */
 -#define SSAM_ANY_TID          0xffff
 -#define SSAM_ANY_IID          0xffff
 -#define SSAM_ANY_FUN          0xffff
 +#define SSAM_SSH_TID_ANY      0xffff
 +#define SSAM_SSH_IID_ANY      0xffff
 +#define SSAM_SSH_FUN_ANY      0xffff
  
  /**
   * SSAM_DEVICE() - Initialize a &struct ssam_device_id with the given
   *
   * Initializes a &struct ssam_device_id with the given parameters. See &struct
   * ssam_device_uid for details regarding the parameters. The special values
 - * %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be used to specify that
 + * %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and %SSAM_SSH_FUN_ANY can be used to specify that
   * matching should ignore target ID, instance ID, and/or sub-function,
   * respectively. This macro initializes the ``match_flags`` field based on the
   * given parameters.
   *
   * Note: The parameters @d and @cat must be valid &u8 values, the parameters
 - * @tid, @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
 - * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
 + * @tid, @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
 + * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values are not
   * allowed.
   */
  #define SSAM_DEVICE(d, cat, tid, iid, fun)                                    \
 -      .match_flags = (((tid) != SSAM_ANY_TID) ? SSAM_MATCH_TARGET : 0)        \
 -                   | (((iid) != SSAM_ANY_IID) ? SSAM_MATCH_INSTANCE : 0)      \
 -                   | (((fun) != SSAM_ANY_FUN) ? SSAM_MATCH_FUNCTION : 0),     \
 +      .match_flags = (((tid) != SSAM_SSH_TID_ANY) ? SSAM_MATCH_TARGET : 0)    \
 +                   | (((iid) != SSAM_SSH_IID_ANY) ? SSAM_MATCH_INSTANCE : 0)  \
 +                   | (((fun) != SSAM_SSH_FUN_ANY) ? SSAM_MATCH_FUNCTION : 0), \
        .domain   = d,                                                          \
        .category = cat,                                                        \
 -      .target   = __builtin_choose_expr((tid) != SSAM_ANY_TID, (tid), 0),     \
 -      .instance = __builtin_choose_expr((iid) != SSAM_ANY_IID, (iid), 0),     \
 -      .function = __builtin_choose_expr((fun) != SSAM_ANY_FUN, (fun), 0)
 +      .target   = __builtin_choose_expr((tid) != SSAM_SSH_TID_ANY, (tid), 0), \
 +      .instance = __builtin_choose_expr((iid) != SSAM_SSH_IID_ANY, (iid), 0), \
 +      .function = __builtin_choose_expr((fun) != SSAM_SSH_FUN_ANY, (fun), 0)
  
  /**
   * SSAM_VDEV() - Initialize a &struct ssam_device_id as virtual device with
   *
   * Initializes a &struct ssam_device_id with the given parameters in the
   * virtual domain. See &struct ssam_device_uid for details regarding the
 - * parameters. The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and
 - * %SSAM_ANY_FUN can be used to specify that matching should ignore target ID,
 + * parameters. The special values %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and
 + * %SSAM_SSH_FUN_ANY can be used to specify that matching should ignore target ID,
   * instance ID, and/or sub-function, respectively. This macro initializes the
   * ``match_flags`` field based on the given parameters.
   *
   * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
 - * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
 - * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
 + * @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
 + * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values are not
   * allowed.
   */
  #define SSAM_VDEV(cat, tid, iid, fun) \
 -      SSAM_DEVICE(SSAM_DOMAIN_VIRTUAL, SSAM_VIRTUAL_TC_##cat, tid, iid, fun)
 +      SSAM_DEVICE(SSAM_DOMAIN_VIRTUAL, SSAM_VIRTUAL_TC_##cat, SSAM_SSH_TID_##tid, iid, fun)
  
  /**
   * SSAM_SDEV() - Initialize a &struct ssam_device_id as physical SSH device
   *
   * Initializes a &struct ssam_device_id with the given parameters in the SSH
   * domain. See &struct ssam_device_uid for details regarding the parameters.
 - * The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be
 - * used to specify that matching should ignore target ID, instance ID, and/or
 - * sub-function, respectively. This macro initializes the ``match_flags``
 - * field based on the given parameters.
 + * The special values %SSAM_SSH_TID_ANY, %SSAM_SSH_IID_ANY, and
 + * %SSAM_SSH_FUN_ANY can be used to specify that matching should ignore target
 + * ID, instance ID, and/or sub-function, respectively. This macro initializes
 + * the ``match_flags`` field based on the given parameters.
   *
   * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
 - * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
 - * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
 - * allowed.
 + * @iid, and @fun must be either valid &u8 values or %SSAM_SSH_TID_ANY,
 + * %SSAM_SSH_IID_ANY, or %SSAM_SSH_FUN_ANY, respectively. Other non-&u8 values
 + * are not allowed.
   */
  #define SSAM_SDEV(cat, tid, iid, fun) \
 -      SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, tid, iid, fun)
 +      SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, SSAM_SSH_TID_##tid, iid, fun)
  
  /*
   * enum ssam_device_flags - Flags for SSAM client devices.
@@@ -229,10 -229,7 +229,7 @@@ static inline bool is_ssam_device(struc
   * Return: Returns a pointer to the &struct ssam_device wrapping the given
   * device @d.
   */
- static inline struct ssam_device *to_ssam_device(struct device *d)
- {
-       return container_of(d, struct ssam_device, dev);
- }
+ #define to_ssam_device(d)     container_of_const(d, struct ssam_device, dev)
  
  /**
   * to_ssam_device_driver() - Casts the given device driver to a SSAM client
@@@ -456,7 -453,7 +453,7 @@@ static inline int ssam_device_register_
   * device of the request and by association the controller via which the
   * request is sent.
   *
 - * Refer to ssam_request_sync_onstack() for more details on the behavior of
 + * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
   * the generated function.
   */
  #define SSAM_DEFINE_SYNC_REQUEST_CL_N(name, spec...)                  \
   * which the request is sent. The request's argument is specified via the
   * ``arg`` pointer.
   *
 - * Refer to ssam_request_sync_onstack() for more details on the behavior of
 + * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
   * the generated function.
   */
  #define SSAM_DEFINE_SYNC_REQUEST_CL_W(name, atype, spec...)           \
   * the request is sent. The request's return value is written to the memory
   * pointed to by the ``ret`` parameter.
   *
 - * Refer to ssam_request_sync_onstack() for more details on the behavior of
 + * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
   * the generated function.
   */
  #define SSAM_DEFINE_SYNC_REQUEST_CL_R(name, rtype, spec...)           \
   * specified via the ``arg`` pointer. The request's return value is written to
   * the memory pointed to by the ``ret`` parameter.
   *
 - * Refer to ssam_request_sync_onstack() for more details on the behavior of
 + * Refer to ssam_request_do_sync_onstack() for more details on the behavior of
   * the generated function.
   */
  #define SSAM_DEFINE_SYNC_REQUEST_CL_WR(name, atype, rtype, spec...)           \
diff --combined include/sound/hdaudio.h
index 536612c6ab0cb01b034dcd5e082970c673f31ac1,1c45664e0e5acf18aa433b1d404f33d6ca3138bc..97f09acae302e3baec76b166d9be95feb7618cbe
@@@ -123,7 -123,7 +123,7 @@@ void snd_hdac_device_exit(struct hdac_d
  int snd_hdac_device_register(struct hdac_device *codec);
  void snd_hdac_device_unregister(struct hdac_device *codec);
  int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
- int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
+ int snd_hdac_codec_modalias(const struct hdac_device *hdac, char *buf, size_t size);
  
  int snd_hdac_refresh_widgets(struct hdac_device *codec);
  
@@@ -575,7 -575,7 +575,7 @@@ void snd_hdac_stream_cleanup(struct hda
  int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev);
  int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
                                unsigned int format_val);
 -void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
 +void snd_hdac_stream_start(struct hdac_stream *azx_dev);
  void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
  void snd_hdac_stop_streams(struct hdac_bus *bus);
  void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);