#include "intel_display_types.h"
 #include "intel_gmbus.h"
 
+struct intel_gmbus {
+       struct i2c_adapter adapter;
+#define GMBUS_FORCE_BIT_RETRY (1U << 31)
+       u32 force_bit;
+       u32 reg0;
+       i915_reg_t gpio_reg;
+       struct i2c_algo_bit_data bit_algo;
+       struct drm_i915_private *dev_priv;
+};
+
 struct gmbus_pin {
        const char *name;
        enum i915_gpio gpio;
                if (!gmbus_pin)
                        continue;
 
-               bus = &dev_priv->gmbus[pin];
+               bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+               if (!bus) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
 
                bus->adapter.owner = THIS_MODULE;
                bus->adapter.class = I2C_CLASS_DDC;
                intel_gpio_setup(bus, GPIO(gmbus_pin->gpio));
 
                ret = i2c_add_adapter(&bus->adapter);
-               if (ret)
+               if (ret) {
+                       kfree(bus);
                        goto err;
+               }
+
+               dev_priv->gmbus[pin] = bus;
        }
 
        intel_gmbus_reset(dev_priv);
        return 0;
 
 err:
-       while (pin--) {
-               if (!intel_gmbus_is_valid_pin(dev_priv, pin))
-                       continue;
+       intel_gmbus_teardown(dev_priv);
 
-               bus = &dev_priv->gmbus[pin];
-               i2c_del_adapter(&bus->adapter);
-       }
        return ret;
 }
 
 struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
                                            unsigned int pin)
 {
-       if (drm_WARN_ON(&dev_priv->drm,
-                       !intel_gmbus_is_valid_pin(dev_priv, pin)))
+       if (drm_WARN_ON(&dev_priv->drm, pin >= ARRAY_SIZE(dev_priv->gmbus) ||
+                       !dev_priv->gmbus[pin]))
                return NULL;
 
-       return &dev_priv->gmbus[pin].adapter;
+       return &dev_priv->gmbus[pin]->adapter;
 }
 
 void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
        unsigned int pin;
 
        for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
-               if (!intel_gmbus_is_valid_pin(dev_priv, pin))
+               bus = dev_priv->gmbus[pin];
+               if (!bus)
                        continue;
 
-               bus = &dev_priv->gmbus[pin];
                i2c_del_adapter(&bus->adapter);
+
+               kfree(bus);
+               dev_priv->gmbus[pin] = NULL;
        }
 }
 
 #include <asm/hypervisor.h>
 
 #include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
 #include <linux/intel-iommu.h>
 #include <linux/pm_qos.h>
 
 struct intel_encoder;
 struct intel_fbdev;
 struct intel_fdi_funcs;
+struct intel_gmbus;
 struct intel_hotplug_funcs;
 struct intel_initial_plane_config;
 struct intel_limit;
 #define QUIRK_INCREASE_DDI_DISABLED_TIME (1<<7)
 #define QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK (1<<8)
 
-struct intel_gmbus {
-       struct i2c_adapter adapter;
-#define GMBUS_FORCE_BIT_RETRY (1U << 31)
-       u32 force_bit;
-       u32 reg0;
-       i915_reg_t gpio_reg;
-       struct i2c_algo_bit_data bit_algo;
-       struct drm_i915_private *dev_priv;
-};
-
 struct i915_suspend_saved_registers {
        u32 saveDSPARB;
        u32 saveSWF0[16];
 
        struct intel_dmc dmc;
 
-       struct intel_gmbus gmbus[GMBUS_NUM_PINS];
+       struct intel_gmbus *gmbus[GMBUS_NUM_PINS];
 
        /** gmbus_mutex protects against concurrent usage of the single hw gmbus
         * controller on different i2c buses. */