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: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
Коммит
ce9557b9fe
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = ®istered_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 = ®istered_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);
|
||||
|
||||
|
|
|
@ -77,3 +77,4 @@ const struct consw dummy_con = {
|
|||
.con_set_palette = DUMMY,
|
||||
.con_scrolldelta = DUMMY,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(dummy_con);
|
||||
|
|
|
@ -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");
|
||||
|
|
Загрузка…
Ссылка в новой задаче