Commit 63a78bbb authored by Jani Nikula's avatar Jani Nikula
Browse files

drm/i915/gmbus: alloc intel_gmbus dynamically



Allocate the individual intel_gmbus structs dynamically. This lets us
hide struct intel_gmbus inside intel_gmbus.c completely. Also use the
cleanup function on the error path to avoid duplication.

Leave #include <linux/i2c.h> in i915_drv.h for now, as it pulls in a
bunch of implicit dependencies.

Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220303181931.1661767-4-jani.nikula@intel.com
parent 65cd963e
Loading
Loading
Loading
Loading
+29 −13
Original line number Diff line number Diff line
@@ -38,6 +38,16 @@
#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;
@@ -881,7 +891,11 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
		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;
@@ -911,33 +925,32 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
		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)
@@ -969,10 +982,13 @@ void intel_gmbus_teardown(struct drm_i915_private *dev_priv)
	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;
	}
}
+2 −12
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@
#include <asm/hypervisor.h>

#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/intel-iommu.h>
#include <linux/pm_qos.h>

@@ -99,6 +98,7 @@ struct intel_dpll_funcs;
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;
@@ -231,16 +231,6 @@ struct i915_drrs {
#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];
@@ -510,7 +500,7 @@ struct drm_i915_private {

	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. */