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

Commit b63254c7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm: ignore EDID with really tiny modes.
  drm: don't associate _DRM_DRIVER maps with a master
  drm/i915: intel_lvds.c fix section mismatch
  drm: Hook up DPMS property handling in drm_crtc.c. Add drm_helper_connector_dpms.
  drm: set permissions on edid file to 0444
  drm: add newlines to text sysfs files
  drm/radeon: fix ring free alignment calculations
  drm: fix irq naming for kms drivers.
parents 730c586a fc438966
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -371,6 +371,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
	list->user_token = list->hash.key << PAGE_SHIFT;
	list->user_token = list->hash.key << PAGE_SHIFT;
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);


	if (!(map->flags & _DRM_DRIVER))
		list->master = dev->primary->master;
		list->master = dev->primary->master;
	*maplist = list;
	*maplist = list;
	return 0;
	return 0;
+6 −1
Original line number Original line Diff line number Diff line
@@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
		}
		}
	}
	}


	if (connector->funcs->set_property)
	/* Do DPMS ourselves */
	if (property == connector->dev->mode_config.dpms_property) {
		if (connector->funcs->dpms)
			(*connector->funcs->dpms)(connector, (int) out_resp->value);
		ret = 0;
	} else if (connector->funcs->set_property)
		ret = connector->funcs->set_property(connector, property, out_resp->value);
		ret = connector->funcs->set_property(connector, property, out_resp->value);


	/* store the property value if succesful */
	/* store the property value if succesful */
+107 −2
Original line number Original line Diff line number Diff line
@@ -198,6 +198,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev,
	}
	}
}
}


/**
 * drm_helper_encoder_in_use - check if a given encoder is in use
 * @encoder: encoder to check
 *
 * LOCKING:
 * Caller must hold mode config lock.
 *
 * Walk @encoders's DRM device's mode_config and see if it's in use.
 *
 * RETURNS:
 * True if @encoder is part of the mode_config, false otherwise.
 */
bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
{
	struct drm_connector *connector;
	struct drm_device *dev = encoder->dev;
	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
		if (connector->encoder == encoder)
			return true;
	return false;
}
EXPORT_SYMBOL(drm_helper_encoder_in_use);

/**
/**
 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
 * @crtc: CRTC to check
 * @crtc: CRTC to check
@@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
	struct drm_device *dev = crtc->dev;
	struct drm_device *dev = crtc->dev;
	/* FIXME: Locking around list access? */
	/* FIXME: Locking around list access? */
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
		if (encoder->crtc == crtc)
		if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
			return true;
			return true;
	return false;
	return false;
}
}
@@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)


	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		encoder_funcs = encoder->helper_private;
		encoder_funcs = encoder->helper_private;
		if (!encoder->crtc)
		if (!drm_helper_encoder_in_use(encoder))
			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
	}
	}


@@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev)
}
}
EXPORT_SYMBOL(drm_helper_initial_config);
EXPORT_SYMBOL(drm_helper_initial_config);


static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
{
	int dpms = DRM_MODE_DPMS_OFF;
	struct drm_connector *connector;
	struct drm_device *dev = encoder->dev;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
		if (connector->encoder == encoder)
			if (connector->dpms < dpms)
				dpms = connector->dpms;
	return dpms;
}

static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
{
	int dpms = DRM_MODE_DPMS_OFF;
	struct drm_connector *connector;
	struct drm_device *dev = crtc->dev;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
		if (connector->encoder && connector->encoder->crtc == crtc)
			if (connector->dpms < dpms)
				dpms = connector->dpms;
	return dpms;
}

/**
 * drm_helper_connector_dpms
 * @connector affected connector
 * @mode DPMS mode
 *
 * Calls the low-level connector DPMS function, then
 * calls appropriate encoder and crtc DPMS functions as well
 */
void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
{
	struct drm_encoder *encoder = connector->encoder;
	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
	int old_dpms;

	if (mode == connector->dpms)
		return;

	old_dpms = connector->dpms;
	connector->dpms = mode;

	/* from off to on, do crtc then encoder */
	if (mode < old_dpms) {
		if (crtc) {
			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
			if (crtc_funcs->dpms)
				(*crtc_funcs->dpms) (crtc,
						     drm_helper_choose_crtc_dpms(crtc));
		}
		if (encoder) {
			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
			if (encoder_funcs->dpms)
				(*encoder_funcs->dpms) (encoder,
							drm_helper_choose_encoder_dpms(encoder));
		}
	}

	/* from on to off, do encoder then crtc */
	if (mode > old_dpms) {
		if (encoder) {
			struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
			if (encoder_funcs->dpms)
				(*encoder_funcs->dpms) (encoder,
							drm_helper_choose_encoder_dpms(encoder));
		}
		if (crtc) {
			struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
			if (crtc_funcs->dpms)
				(*crtc_funcs->dpms) (crtc,
						     drm_helper_choose_crtc_dpms(crtc));
		}
	}

	return;
}
EXPORT_SYMBOL(drm_helper_connector_dpms);

/**
/**
 * drm_hotplug_stage_two
 * drm_hotplug_stage_two
 * @dev DRM device
 * @dev DRM device
+5 −0
Original line number Original line Diff line number Diff line
@@ -289,6 +289,11 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
	struct drm_display_mode *mode;
	struct drm_display_mode *mode;
	struct detailed_pixel_timing *pt = &timing->data.pixel_data;
	struct detailed_pixel_timing *pt = &timing->data.pixel_data;


	/* ignore tiny modes */
	if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 ||
	    ((pt->vactive_hi << 8) | pt->hactive_lo) < 64)
		return NULL;

	if (pt->stereo) {
	if (pt->stereo) {
		printk(KERN_WARNING "stereo mode not supported\n");
		printk(KERN_WARNING "stereo mode not supported\n");
		return NULL;
		return NULL;
+7 −1
Original line number Original line Diff line number Diff line
@@ -196,6 +196,7 @@ int drm_irq_install(struct drm_device *dev)
{
{
	int ret = 0;
	int ret = 0;
	unsigned long sh_flags = 0;
	unsigned long sh_flags = 0;
	char *irqname;


	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
		return -EINVAL;
		return -EINVAL;
@@ -227,8 +228,13 @@ int drm_irq_install(struct drm_device *dev)
	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
		sh_flags = IRQF_SHARED;
		sh_flags = IRQF_SHARED;


	if (dev->devname)
		irqname = dev->devname;
	else
		irqname = dev->driver->name;

	ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
	ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
			  sh_flags, dev->devname, dev);
			  sh_flags, irqname, dev);


	if (ret < 0) {
	if (ret < 0) {
		mutex_lock(&dev->struct_mutex);
		mutex_lock(&dev->struct_mutex);
Loading