#define __raw_posting_read(...) ((void)__raw_uncore_read32(__VA_ARGS__))
 
+static void
+fw_domains_get(struct intel_uncore *uncore, enum forcewake_domains fw_domains)
+{
+       uncore->fw_get_funcs->force_wake_get(uncore, fw_domains);
+}
+
 void
 intel_uncore_mmio_debug_init_early(struct intel_uncore_mmio_debug *mmio_debug)
 {
 }
 
 static void
-fw_domains_get(struct intel_uncore *uncore, enum forcewake_domains fw_domains)
+fw_domains_get_normal(struct intel_uncore *uncore, enum forcewake_domains fw_domains)
 {
        struct intel_uncore_forcewake_domain *d;
        unsigned int tmp;
 
        GEM_BUG_ON(!domain->wake_count);
        if (--domain->wake_count == 0)
-               uncore->funcs.force_wake_put(uncore, domain->mask);
+               fw_domains_put(uncore, domain->mask);
 
        spin_unlock_irqrestore(&uncore->lock, irqflags);
 
 
        fw = uncore->fw_domains_active;
        if (fw)
-               uncore->funcs.force_wake_put(uncore, fw);
+               fw_domains_put(uncore, fw);
 
        fw_domains_reset(uncore, uncore->fw_domains);
        assert_forcewakes_inactive(uncore);
        intel_uncore_forcewake_reset(uncore);
        if (restore_forcewake) {
                spin_lock_irq(&uncore->lock);
-               uncore->funcs.force_wake_get(uncore, restore_forcewake);
+               fw_domains_get(uncore, restore_forcewake);
 
                if (intel_uncore_has_fifo(uncore))
                        uncore->fifo_count = fifo_free_entries(uncore);
        }
 
        if (fw_domains)
-               uncore->funcs.force_wake_get(uncore, fw_domains);
+               fw_domains_get(uncore, fw_domains);
 }
 
 /**
 {
        unsigned long irqflags;
 
-       if (!uncore->funcs.force_wake_get)
+       if (!uncore->fw_get_funcs)
                return;
 
        assert_rpm_wakelock_held(uncore->rpm);
 {
        lockdep_assert_held(&uncore->lock);
 
-       if (!uncore->funcs.force_wake_get)
+       if (!uncore->fw_get_funcs)
                return;
 
        __intel_uncore_forcewake_get(uncore, fw_domains);
                        continue;
                }
 
-               uncore->funcs.force_wake_put(uncore, domain->mask);
+               fw_domains_put(uncore, domain->mask);
        }
 }
 
 {
        unsigned long irqflags;
 
-       if (!uncore->funcs.force_wake_put)
+       if (!uncore->fw_get_funcs)
                return;
 
        spin_lock_irqsave(&uncore->lock, irqflags);
        struct intel_uncore_forcewake_domain *domain;
        unsigned int tmp;
 
-       if (!uncore->funcs.force_wake_put)
+       if (!uncore->fw_get_funcs)
                return;
 
        fw_domains &= uncore->fw_domains;
 {
        lockdep_assert_held(&uncore->lock);
 
-       if (!uncore->funcs.force_wake_put)
+       if (!uncore->fw_get_funcs)
                return;
 
        __intel_uncore_forcewake_put(uncore, fw_domains);
 
 void assert_forcewakes_inactive(struct intel_uncore *uncore)
 {
-       if (!uncore->funcs.force_wake_get)
+       if (!uncore->fw_get_funcs)
                return;
 
        drm_WARN(&uncore->i915->drm, uncore->fw_domains_active,
        if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM))
                return;
 
-       if (!uncore->funcs.force_wake_get)
+       if (!uncore->fw_get_funcs)
                return;
 
        spin_lock_irq(&uncore->lock);
        for_each_fw_domain_masked(domain, fw_domains, uncore, tmp)
                fw_domain_arm_timer(domain);
 
-       uncore->funcs.force_wake_get(uncore, fw_domains);
+       fw_domains_get(uncore, fw_domains);
 }
 
 static inline void __force_wake_auto(struct intel_uncore *uncore,
                fw_domain_fini(uncore, d->id);
 }
 
+static const struct intel_uncore_fw_get uncore_get_fallback = {
+       .force_wake_get = fw_domains_get_with_fallback
+};
+
+static const struct intel_uncore_fw_get uncore_get_normal = {
+       .force_wake_get = fw_domains_get_normal,
+};
+
+static const struct intel_uncore_fw_get uncore_get_thread_status = {
+       .force_wake_get = fw_domains_get_with_thread_status
+};
+
 static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
 {
        struct drm_i915_private *i915 = uncore->i915;
                intel_engine_mask_t emask = INTEL_INFO(i915)->platform_engine_mask;
                int i;
 
-               uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_fallback;
                fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE_RENDER_GEN9,
                               FORCEWAKE_ACK_RENDER_GEN9);
                                       FORCEWAKE_ACK_MEDIA_VEBOX_GEN11(i));
                }
        } else if (IS_GRAPHICS_VER(i915, 9, 10)) {
-               uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_fallback;
                fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE_RENDER_GEN9,
                               FORCEWAKE_ACK_RENDER_GEN9);
                fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
                               FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
        } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
-               uncore->funcs.force_wake_get = fw_domains_get;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_normal;
                fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
                fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
                               FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
        } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
-               uncore->funcs.force_wake_get =
-                       fw_domains_get_with_thread_status;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_thread_status;
                fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
        } else if (IS_IVYBRIDGE(i915)) {
                 * (correctly) interpreted by the test below as MT
                 * forcewake being disabled.
                 */
-               uncore->funcs.force_wake_get =
-                       fw_domains_get_with_thread_status;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_thread_status;
 
                /* We need to init first for ECOBUS access and then
                 * determine later if we want to reinit, in case of MT access is
                                       FORCEWAKE, FORCEWAKE_ACK);
                }
        } else if (GRAPHICS_VER(i915) == 6) {
-               uncore->funcs.force_wake_get =
-                       fw_domains_get_with_thread_status;
-               uncore->funcs.force_wake_put = fw_domains_put;
+               uncore->fw_get_funcs = &uncore_get_thread_status;
                fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
                               FORCEWAKE, FORCEWAKE_ACK);
        }
        }
 
        /* make sure fw funcs are set if and only if we have fw*/
-       GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_get);
-       GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_put);
+       GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->fw_get_funcs);
        GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.read_fw_domains);
        GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.write_fw_domains);