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

Commit ce9557b9 authored by Jani Nikula's avatar Jani Nikula
Browse files

Merge remote-tracking branch 'drm-intel/topic/kicking-dogs-and-vgacon' into drm-intel-fixes

vt/vgacon fixes to avoid hangs, unclaimed register errors on module
load, reload:

vt: Fix replacement console check when unbinding
vt: Fix up unregistration of vt drivers
vt: Don't ignore unbind errors in vt_unbind
drm/i915: Fixup global gtt cleanup
drm/i915: Kick out vga console

Link: http://lkml.kernel.org/r/1401980308-5116-1-git-send-email-daniel.vetter@ffwll.ch


Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parents 329ff963 a4de0526
Loading
Loading
Loading
Loading
+42 −5
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include <linux/pci.h>
#include <linux/console.h>
#include <linux/vt.h>
#include <linux/vgaarb.h>
#include <linux/acpi.h>
#include <linux/pnp.h>
@@ -1386,7 +1388,6 @@ cleanup_gem:
	i915_gem_context_fini(dev);
	mutex_unlock(&dev->struct_mutex);
	WARN_ON(dev_priv->mm.aliasing_ppgtt);
	drm_mm_takedown(&dev_priv->gtt.base.mm);
cleanup_irq:
	drm_irq_uninstall(dev);
cleanup_gem_stolen:
@@ -1450,6 +1451,38 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
}
#endif

#if !defined(CONFIG_VGA_CONSOLE)
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
	return 0;
}
#elif !defined(CONFIG_DUMMY_CONSOLE)
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
	return -ENODEV;
}
#else
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
	int ret;

	DRM_INFO("Replacing VGA console driver\n");

	console_lock();
	ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
	if (ret == 0) {
		ret = do_unregister_con_driver(&vga_con);

		/* Ignore "already unregistered". */
		if (ret == -ENODEV)
			ret = 0;
	}
	console_unlock();

	return ret;
}
#endif

static void i915_dump_device_info(struct drm_i915_private *dev_priv)
{
	const struct intel_device_info *info = &dev_priv->info;
@@ -1623,8 +1656,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	if (ret)
		goto out_regs;

	if (drm_core_check_feature(dev, DRIVER_MODESET))
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		ret = i915_kick_out_vgacon(dev_priv);
		if (ret) {
			DRM_ERROR("failed to remove conflicting VGA console\n");
			goto out_gtt;
		}

		i915_kick_out_firmware_fb(dev_priv);
	}

	pci_set_master(dev->pdev);

@@ -1756,8 +1796,6 @@ out_mtrrfree:
	arch_phys_wc_del(dev_priv->gtt.mtrr);
	io_mapping_free(dev_priv->gtt.mappable);
out_gtt:
	list_del(&dev_priv->gtt.base.global_link);
	drm_mm_takedown(&dev_priv->gtt.base.mm);
	dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
out_regs:
	intel_uncore_fini(dev);
@@ -1846,7 +1884,6 @@ int i915_driver_unload(struct drm_device *dev)
			i915_free_hws(dev);
	}

	list_del(&dev_priv->gtt.base.global_link);
	WARN_ON(!list_empty(&dev_priv->vm_list));

	drm_vblank_cleanup(dev);
+8 −1
Original line number Diff line number Diff line
@@ -1992,7 +1992,10 @@ static void gen6_gmch_remove(struct i915_address_space *vm)

	struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base);

	if (drm_mm_initialized(&vm->mm)) {
		drm_mm_takedown(&vm->mm);
		list_del(&vm->global_link);
	}
	iounmap(gtt->gsm);
	teardown_scratch_page(vm->dev);
}
@@ -2025,6 +2028,10 @@ static int i915_gmch_probe(struct drm_device *dev,

static void i915_gmch_remove(struct i915_address_space *vm)
{
	if (drm_mm_initialized(&vm->mm)) {
		drm_mm_takedown(&vm->mm);
		list_del(&vm->global_link);
	}
	intel_gmch_remove();
}

+14 −10
Original line number Diff line number Diff line
@@ -3155,8 +3155,7 @@ int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt
	for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
		con_back = &registered_con_driver[i];

		if (con_back->con &&
		    !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
		if (con_back->con && con_back->con != csw) {
			defcsw = con_back->con;
			retval = 0;
			break;
@@ -3261,6 +3260,7 @@ static int vt_unbind(struct con_driver *con)
{
	const struct consw *csw = NULL;
	int i, more = 1, first = -1, last = -1, deflt = 0;
	int ret;

 	if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
	    con_is_graphics(con->con, con->first, con->last))
@@ -3286,8 +3286,10 @@ static int vt_unbind(struct con_driver *con)

		if (first != -1) {
			console_lock();
			do_unbind_con_driver(csw, first, last, deflt);
			ret = do_unbind_con_driver(csw, first, last, deflt);
			console_unlock();
			if (ret != 0)
				return ret;
		}

		first = -1;
@@ -3574,17 +3576,20 @@ err:
 */
int do_unregister_con_driver(const struct consw *csw)
{
	int i, retval = -ENODEV;
	int i;

	/* cannot unregister a bound driver */
	if (con_is_bound(csw))
		goto err;
		return -EBUSY;

	if (csw == conswitchp)
		return -EINVAL;

	for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
		struct con_driver *con_driver = &registered_con_driver[i];

		if (con_driver->con == csw &&
		    con_driver->flag & CON_DRIVER_FLAG_MODULE) {
		    con_driver->flag & CON_DRIVER_FLAG_INIT) {
			vtconsole_deinit_device(con_driver);
			device_destroy(vtconsole_class,
				       MKDEV(0, con_driver->node));
@@ -3595,12 +3600,11 @@ int do_unregister_con_driver(const struct consw *csw)
			con_driver->flag = 0;
			con_driver->first = 0;
			con_driver->last = 0;
			retval = 0;
			break;
			return 0;
		}
	}
err:
	return retval;

	return -ENODEV;
}
EXPORT_SYMBOL_GPL(do_unregister_con_driver);

+1 −0
Original line number Diff line number Diff line
@@ -77,3 +77,4 @@ const struct consw dummy_con = {
    .con_set_palette =	DUMMY,
    .con_scrolldelta =	DUMMY,
};
EXPORT_SYMBOL_GPL(dummy_con);
+1 −0
Original line number Diff line number Diff line
@@ -1440,5 +1440,6 @@ const struct consw vga_con = {
	.con_build_attr = vgacon_build_attr,
	.con_invert_region = vgacon_invert_region,
};
EXPORT_SYMBOL(vga_con);

MODULE_LICENSE("GPL");