pm_runtime_put_sync(ksm->dev);
 }
 
+static inline bool blk_ksm_is_passthrough(struct blk_keyslot_manager *ksm)
+{
+       return ksm->num_slots == 0;
+}
+
 /**
  * blk_ksm_init() - Initialize a keyslot manager
  * @ksm: The keyslot_manager to initialize.
        int err;
 
        *slot_ptr = NULL;
+
+       if (blk_ksm_is_passthrough(ksm))
+               return BLK_STS_OK;
+
        down_read(&ksm->lock);
        slot = blk_ksm_find_and_grab_keyslot(ksm, key);
        up_read(&ksm->lock);
        struct blk_ksm_keyslot *slot;
        int err = 0;
 
+       if (blk_ksm_is_passthrough(ksm)) {
+               if (ksm->ksm_ll_ops.keyslot_evict) {
+                       blk_ksm_hw_enter(ksm);
+                       err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, -1);
+                       blk_ksm_hw_exit(ksm);
+                       return err;
+               }
+               return 0;
+       }
+
        blk_ksm_hw_enter(ksm);
        slot = blk_ksm_find_keyslot(ksm, key);
        if (!slot)
 {
        unsigned int slot;
 
+       if (blk_ksm_is_passthrough(ksm))
+               return;
+
        /* This is for device initialization, so don't resume the device */
        down_write(&ksm->lock);
        for (slot = 0; slot < ksm->num_slots; slot++) {
 {
        q->ksm = NULL;
 }
+
+/**
+ * blk_ksm_init_passthrough() - Init a passthrough keyslot manager
+ * @ksm: The keyslot manager to init
+ *
+ * Initialize a passthrough keyslot manager.
+ * Called by e.g. storage drivers to set up a keyslot manager in their
+ * request_queue, when the storage driver wants to manage its keys by itself.
+ * This is useful for inline encryption hardware that doesn't have the concept
+ * of keyslots, and for layered devices.
+ */
+void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm)
+{
+       memset(ksm, 0, sizeof(*ksm));
+       init_rwsem(&ksm->lock);
+}
+EXPORT_SYMBOL_GPL(blk_ksm_init_passthrough);