Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bd7d909 authored by Daniel Kurtz's avatar Daniel Kurtz Committed by Daniel Vetter
Browse files

drm/i915/intel_i2c: refactor using intel_gmbus_get_adapter



Instead of letting other modules directly access the ->gmbus array,
introduce intel_gmbus_get_adapter() for looking up an i2c_adapter
for a given gmbus port identifier.  This will enable later refactoring
of the gmbus port list.

Note: Before requesting an adapter for a given gmbus port number, the
driver must first check its validity using i2c_intel_gmbus_is_port_valid().
If this check fails, a call to intel_gmbus_get_adapter() will WARN_ON and
return NULL.  This is relevant for parts of the driver that read a port
from VBIOS, which might be improperly initialized and contain an invalid
port.  In these cases, the driver must fall back to using a safer default
port.

Signed-off-by: default avatarDaniel Kurtz <djkurtz@chromium.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 489fbc10
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -1342,6 +1342,13 @@ extern int i915_restore_state(struct drm_device *dev);
/* intel_i2c.c */
/* intel_i2c.c */
extern int intel_setup_gmbus(struct drm_device *dev);
extern int intel_setup_gmbus(struct drm_device *dev);
extern void intel_teardown_gmbus(struct drm_device *dev);
extern void intel_teardown_gmbus(struct drm_device *dev);
extern inline bool intel_gmbus_is_port_valid(unsigned port)
{
	return (port >= GMBUS_PORT_DISABLED && port <= GMBUS_PORT_RESERVED);
}

extern struct i2c_adapter *intel_gmbus_get_adapter(
		struct drm_i915_private *dev_priv, unsigned port);
extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
+2 −2
Original line number Original line Diff line number Diff line
@@ -372,7 +372,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
		if (block_size >= sizeof(*general)) {
		if (block_size >= sizeof(*general)) {
			int bus_pin = general->crt_ddc_gmbus_pin;
			int bus_pin = general->crt_ddc_gmbus_pin;
			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
			if (bus_pin >= 1 && bus_pin <= 6)
			if (intel_gmbus_is_port_valid(bus_pin))
				dev_priv->crt_ddc_pin = bus_pin;
				dev_priv->crt_ddc_pin = bus_pin;
		} else {
		} else {
			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
+8 −6
Original line number Original line Diff line number Diff line
@@ -278,9 +278,10 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
	if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
	if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
		struct edid *edid;
		struct edid *edid;
		bool is_digital = false;
		bool is_digital = false;
		struct i2c_adapter *i2c;


		edid = drm_get_edid(connector,
		i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
			&dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
		edid = drm_get_edid(connector, i2c);
		/*
		/*
		 * This may be a DVI-I connector with a shared DDC
		 * This may be a DVI-I connector with a shared DDC
		 * link between analog and digital outputs, so we
		 * link between analog and digital outputs, so we
@@ -483,15 +484,16 @@ static int intel_crt_get_modes(struct drm_connector *connector)
	struct drm_device *dev = connector->dev;
	struct drm_device *dev = connector->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret;
	int ret;
	struct i2c_adapter *i2c;


	ret = intel_ddc_get_modes(connector,
	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
				 &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
	ret = intel_ddc_get_modes(connector, i2c);
	if (ret || !IS_G4X(dev))
	if (ret || !IS_G4X(dev))
		return ret;
		return ret;


	/* Try to probe digital port for output in DVI-I -> VGA mode. */
	/* Try to probe digital port for output in DVI-I -> VGA mode. */
	return intel_ddc_get_modes(connector,
	i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
				   &dev_priv->gmbus[GMBUS_PORT_DPB].adapter);
	return intel_ddc_get_modes(connector, i2c);
}
}


static int intel_crt_set_property(struct drm_connector *connector,
static int intel_crt_set_property(struct drm_connector *connector,
+3 −3
Original line number Original line Diff line number Diff line
@@ -243,7 +243,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
	 * that's not the case.
	 * that's not the case.
	 */
	 */
	intel_ddc_get_modes(connector,
	intel_ddc_get_modes(connector,
			    &dev_priv->gmbus[GMBUS_PORT_DPC].adapter);
			    intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPC));
	if (!list_empty(&connector->probed_modes))
	if (!list_empty(&connector->probed_modes))
		return 1;
		return 1;


@@ -375,7 +375,7 @@ void intel_dvo_init(struct drm_device *dev)
		 * special cases, but otherwise default to what's defined
		 * special cases, but otherwise default to what's defined
		 * in the spec.
		 * in the spec.
		 */
		 */
		if (dvo->gpio != 0)
		if (intel_gmbus_is_port_valid(dvo->gpio))
			gpio = dvo->gpio;
			gpio = dvo->gpio;
		else if (dvo->type == INTEL_DVO_CHIP_LVDS)
		else if (dvo->type == INTEL_DVO_CHIP_LVDS)
			gpio = GMBUS_PORT_SSC;
			gpio = GMBUS_PORT_SSC;
@@ -386,7 +386,7 @@ void intel_dvo_init(struct drm_device *dev)
		 * It appears that everything is on GPIOE except for panels
		 * It appears that everything is on GPIOE except for panels
		 * on i830 laptops, which are on GPIOB (DVOA).
		 * on i830 laptops, which are on GPIOB (DVOA).
		 */
		 */
		i2c = &dev_priv->gmbus[gpio].adapter;
		i2c = intel_gmbus_get_adapter(dev_priv, gpio);


		intel_dvo->dev = *dvo;
		intel_dvo->dev = *dvo;
		if (!dvo->dev_ops->init(&intel_dvo->dev, i2c))
		if (!dvo->dev_ops->init(&intel_dvo->dev, i2c))
+6 −3
Original line number Original line Diff line number Diff line
@@ -334,7 +334,8 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_hdmi_sink = false;
	intel_hdmi->has_audio = false;
	intel_hdmi->has_audio = false;
	edid = drm_get_edid(connector,
	edid = drm_get_edid(connector,
			    &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));


	if (edid) {
	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
@@ -367,7 +368,8 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
	 */
	 */


	return intel_ddc_get_modes(connector,
	return intel_ddc_get_modes(connector,
				   &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
				   intel_gmbus_get_adapter(dev_priv,
							   intel_hdmi->ddc_bus));
}
}


static bool
static bool
@@ -379,7 +381,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
	bool has_audio = false;
	bool has_audio = false;


	edid = drm_get_edid(connector,
	edid = drm_get_edid(connector,
			    &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
			    intel_gmbus_get_adapter(dev_priv,
						    intel_hdmi->ddc_bus));
	if (edid) {
	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL)
		if (edid->input & DRM_EDID_INPUT_DIGITAL)
			has_audio = drm_detect_monitor_audio(edid);
			has_audio = drm_detect_monitor_audio(edid);
Loading