return (u64)udw << 32 | ldw;
 }
 
+/**
+ * xe_mmio_wait32() - Wait for a register to match the desired masked value
+ * @gt: MMIO target GT
+ * @reg: register to read value from
+ * @mask: mask to be applied to the value read from the register
+ * @val: desired value after applying the mask
+ * @timeout_us: time out after this period of time. Wait logic tries to be
+ * smart, applying an exponential backoff until @timeout_us is reached.
+ * @out_val: if not NULL, points where to store the last unmasked value
+ * @atomic: needs to be true if calling from an atomic context
+ *
+ * This function polls for the desired masked value and returns zero on success
+ * or -ETIMEDOUT if timed out.
+ *
+ * Note that @timeout_us represents the minimum amount of time to wait before
+ * giving up. The actual time taken by this function can be a little more than
+ * @timeout_us for different reasons, specially in non-atomic contexts. Thus,
+ * it is possible that this function succeeds even after @timeout_us has passed.
+ */
+int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+                  u32 *out_val, bool atomic)
+{
+       ktime_t cur = ktime_get_raw();
+       const ktime_t end = ktime_add_us(cur, timeout_us);
+       int ret = -ETIMEDOUT;
+       s64 wait = 10;
+       u32 read;
+
+       for (;;) {
+               read = xe_mmio_read32(gt, reg);
+               if ((read & mask) == val) {
+                       ret = 0;
+                       break;
+               }
+
+               cur = ktime_get_raw();
+               if (!ktime_before(cur, end))
+                       break;
+
+               if (ktime_after(ktime_add_us(cur, wait), end))
+                       wait = ktime_us_delta(end, cur);
+
+               if (atomic)
+                       udelay(wait);
+               else
+                       usleep_range(wait, wait << 1);
+               wait <<= 1;
+       }
+
+       if (out_val)
+               *out_val = read;
+
+       return ret;
+}
 
        return (reg_val & mask) != eval ? -EINVAL : 0;
 }
 
-static inline int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask,
-                                u32 val, u32 timeout_us, u32 *out_val,
-                                bool atomic)
-{
-       ktime_t cur = ktime_get_raw();
-       const ktime_t end = ktime_add_us(cur, timeout_us);
-       int ret = -ETIMEDOUT;
-       s64 wait = 10;
-       u32 read;
-
-       for (;;) {
-               read = xe_mmio_read32(gt, reg);
-               if ((read & mask) == val) {
-                       ret = 0;
-                       break;
-               }
-
-               cur = ktime_get_raw();
-               if (!ktime_before(cur, end))
-                       break;
-
-               if (ktime_after(ktime_add_us(cur, wait), end))
-                       wait = ktime_us_delta(end, cur);
-
-               if (atomic)
-                       udelay(wait);
-               else
-                       usleep_range(wait, wait << 1);
-               wait <<= 1;
-       }
-
-       if (out_val)
-               *out_val = read;
-
-       return ret;
-}
-
 static inline bool xe_mmio_in_range(const struct xe_gt *gt,
                                    const struct xe_mmio_range *range,
                                    struct xe_reg reg)
 
 int xe_mmio_probe_vram(struct xe_device *xe);
 u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg);
+int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+                  u32 *out_val, bool atomic);
 
 #endif