]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Feb 2013 04:46:23 +0000 (20:46 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Feb 2013 04:46:23 +0000 (20:46 -0800)
added patches:
drm-radeon-dce6-fix-display-powergating.patch
drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch
drm-radeon-properly-validate-the-atpx-interface.patch
drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch
drm-udl-disable-fb_defio-by-default.patch
drm-udl-make-usage-as-a-console-safer.patch
vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch

queue-3.8/drm-radeon-dce6-fix-display-powergating.patch [new file with mode: 0644]
queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch [new file with mode: 0644]
queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch [new file with mode: 0644]
queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch [new file with mode: 0644]
queue-3.8/drm-udl-disable-fb_defio-by-default.patch [new file with mode: 0644]
queue-3.8/drm-udl-make-usage-as-a-console-safer.patch [new file with mode: 0644]
queue-3.8/series
queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch [new file with mode: 0644]

diff --git a/queue-3.8/drm-radeon-dce6-fix-display-powergating.patch b/queue-3.8/drm-radeon-dce6-fix-display-powergating.patch
new file mode 100644 (file)
index 0000000..07f676f
--- /dev/null
@@ -0,0 +1,50 @@
+From 0e3d50bfcbd338254795a700dcff429a96cba1a6 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 5 Feb 2013 11:47:09 -0500
+Subject: drm/radeon/dce6: fix display powergating
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 0e3d50bfcbd338254795a700dcff429a96cba1a6 upstream.
+
+Only enable it when we disable the display rather than
+at DPMS time since enabling it requires a full modeset
+to restore the display state.  Fixes blank screens in
+certain cases.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_crtc.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -252,8 +252,6 @@ void atombios_crtc_dpms(struct drm_crtc
+               radeon_crtc->enabled = true;
+               /* adjust pm to dpms changes BEFORE enabling crtcs */
+               radeon_pm_compute_clocks(rdev);
+-              if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+-                      atombios_powergate_crtc(crtc, ATOM_DISABLE);
+               atombios_enable_crtc(crtc, ATOM_ENABLE);
+               if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
+                       atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
+@@ -271,8 +269,6 @@ void atombios_crtc_dpms(struct drm_crtc
+                       atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
+               atombios_enable_crtc(crtc, ATOM_DISABLE);
+               radeon_crtc->enabled = false;
+-              if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+-                      atombios_powergate_crtc(crtc, ATOM_ENABLE);
+               /* adjust pm to dpms changes AFTER disabling crtcs */
+               radeon_pm_compute_clocks(rdev);
+               break;
+@@ -1844,6 +1840,8 @@ static void atombios_crtc_disable(struct
+       int i;
+       atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
++      if (ASIC_IS_DCE6(rdev))
++              atombios_powergate_crtc(crtc, ATOM_ENABLE);
+       for (i = 0; i < rdev->num_crtc; i++) {
+               if (rdev->mode_info.crtcs[i] &&
diff --git a/queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch b/queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch
new file mode 100644 (file)
index 0000000..97b5c23
--- /dev/null
@@ -0,0 +1,52 @@
+From 7ae764b11ed63279e9dcf25be972ff4ca21a9875 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 11 Feb 2013 08:44:48 -0500
+Subject: drm/radeon: fix multi-head power profile stability on BTC+ asics
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 7ae764b11ed63279e9dcf25be972ff4ca21a9875 upstream.
+
+vddci needs to track mclk for multi-head.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c |   13 +++++++++++++
+ drivers/gpu/drm/radeon/radeon_pm.c |    2 +-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -403,6 +403,19 @@ void evergreen_pm_misc(struct radeon_dev
+                       rdev->pm.current_vddc = voltage->voltage;
+                       DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
+               }
++
++              /* starting with BTC, there is one state that is used for both
++               * MH and SH.  Difference is that we always use the high clock index for
++               * mclk and vddci.
++               */
++              if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
++                  (rdev->family >= CHIP_BARTS) &&
++                  rdev->pm.active_crtc_count &&
++                  ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
++                   (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
++                      voltage = &rdev->pm.power_state[req_ps_idx].
++                              clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
++
+               /* 0xff01 is a flag rather then an actual voltage */
+               if (voltage->vddci == 0xff01)
+                       return;
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -169,7 +169,7 @@ static void radeon_set_power_state(struc
+               /* starting with BTC, there is one state that is used for both
+                * MH and SH.  Difference is that we always use the high clock index for
+-               * mclk.
++               * mclk and vddci.
+                */
+               if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
+                   (rdev->family >= CHIP_BARTS) &&
diff --git a/queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch b/queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch
new file mode 100644 (file)
index 0000000..9ccba10
--- /dev/null
@@ -0,0 +1,121 @@
+From 43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 19 Feb 2013 12:55:52 -0500
+Subject: drm/radeon: properly validate the atpx interface
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 upstream.
+
+Some bioses don't set the function mask correctly
+which caused required functions to be disabled.
+
+Fixes:
+https://bugzilla.kernel.org/show_bug.cgi?id=53111
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_atpx_handler.c |   73 ++++++++++++++++++++++++++-
+ 1 file changed, 71 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+@@ -43,6 +43,12 @@ struct atpx_verify_interface {
+       u32 function_bits;      /* supported functions bit vector */
+ } __packed;
++struct atpx_px_params {
++      u16 size;               /* structure size in bytes (includes size field) */
++      u32 valid_flags;        /* which flags are valid */
++      u32 flags;              /* flags */
++} __packed;
++
+ struct atpx_power_control {
+       u16 size;
+       u8 dgpu_state;
+@@ -123,9 +129,61 @@ static void radeon_atpx_parse_functions(
+ }
+ /**
++ * radeon_atpx_validate_functions - validate ATPX functions
++ *
++ * @atpx: radeon atpx struct
++ *
++ * Validate that required functions are enabled (all asics).
++ * returns 0 on success, error on failure.
++ */
++static int radeon_atpx_validate(struct radeon_atpx *atpx)
++{
++      /* make sure required functions are enabled */
++      /* dGPU power control is required */
++      atpx->functions.power_cntl = true;
++
++      if (atpx->functions.px_params) {
++              union acpi_object *info;
++              struct atpx_px_params output;
++              size_t size;
++              u32 valid_bits;
++
++              info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
++              if (!info)
++                      return -EIO;
++
++              memset(&output, 0, sizeof(output));
++
++              size = *(u16 *) info->buffer.pointer;
++              if (size < 10) {
++                      printk("ATPX buffer is too small: %zu\n", size);
++                      kfree(info);
++                      return -EINVAL;
++              }
++              size = min(sizeof(output), size);
++
++              memcpy(&output, info->buffer.pointer, size);
++
++              valid_bits = output.flags & output.valid_flags;
++              /* if separate mux flag is set, mux controls are required */
++              if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
++                      atpx->functions.i2c_mux_cntl = true;
++                      atpx->functions.disp_mux_cntl = true;
++              }
++              /* if any outputs are muxed, mux controls are required */
++              if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
++                                ATPX_TV_SIGNAL_MUXED |
++                                ATPX_DFP_SIGNAL_MUXED))
++                      atpx->functions.disp_mux_cntl = true;
++
++              kfree(info);
++      }
++      return 0;
++}
++
++/**
+  * radeon_atpx_verify_interface - verify ATPX
+  *
+- * @handle: acpi handle
+  * @atpx: radeon atpx struct
+  *
+  * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
+@@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle
+  */
+ static int radeon_atpx_init(void)
+ {
++      int r;
++
+       /* set up the ATPX handle */
+-      return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
++      r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
++      if (r)
++              return r;
++
++      /* validate the atpx setup */
++      r = radeon_atpx_validate(&radeon_atpx_priv.atpx);
++      if (r)
++              return r;
++
++      return 0;
+ }
+ /**
diff --git a/queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch b/queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch
new file mode 100644 (file)
index 0000000..b8af734
--- /dev/null
@@ -0,0 +1,32 @@
+From c944b2abb067130542055666f23409fd5e1afc8e Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 12 Feb 2013 08:39:10 -0500
+Subject: drm/radeon: remove overzealous warning in hdmi handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit c944b2abb067130542055666f23409fd5e1afc8e upstream.
+
+hdmi audio works fine.  The warning just confuses users.
+
+fixes:
+https://bugzilla.kernel.org/show_bug.cgi?id=44341
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Jerome Glisse <jglisse@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/r600_hdmi.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/r600_hdmi.c
++++ b/drivers/gpu/drm/radeon/r600_hdmi.c
+@@ -544,7 +544,6 @@ void r600_hdmi_disable(struct drm_encode
+       /* Called for ATOM_ENCODER_MODE_HDMI only */
+       if (!dig || !dig->afmt) {
+-              WARN_ON(1);
+               return;
+       }
+       if (!dig->afmt->enabled)
diff --git a/queue-3.8/drm-udl-disable-fb_defio-by-default.patch b/queue-3.8/drm-udl-disable-fb_defio-by-default.patch
new file mode 100644 (file)
index 0000000..1da6b5a
--- /dev/null
@@ -0,0 +1,35 @@
+From 677d23b70bf949f75746c80cbae92c233c6b5e2a Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Thu, 7 Feb 2013 12:30:25 +1000
+Subject: drm/udl: disable fb_defio by default
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit 677d23b70bf949f75746c80cbae92c233c6b5e2a upstream.
+
+There seems to be a bad interaction between gem/shmem and defio on top,
+I get list corruption on the page lru in the shmem code.
+
+Turn it off for now until we get some more digging done.
+
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_fb.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/udl/udl_fb.c
++++ b/drivers/gpu/drm/udl/udl_fb.c
+@@ -22,9 +22,9 @@
+ #include <drm/drm_fb_helper.h>
+-#define DL_DEFIO_WRITE_DELAY    5 /* fb_deferred_io.delay in jiffies */
++#define DL_DEFIO_WRITE_DELAY    (HZ/20) /* fb_deferred_io.delay in jiffies */
+-static int fb_defio = 1;  /* Optionally enable experimental fb_defio mmap support */
++static int fb_defio = 0;  /* Optionally enable experimental fb_defio mmap support */
+ static int fb_bpp = 16;
+ module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
diff --git a/queue-3.8/drm-udl-make-usage-as-a-console-safer.patch b/queue-3.8/drm-udl-make-usage-as-a-console-safer.patch
new file mode 100644 (file)
index 0000000..9e7f329
--- /dev/null
@@ -0,0 +1,124 @@
+From bcb39af4486be07e896fc374a2336bad3104ae0a Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Thu, 7 Feb 2013 11:19:15 +1000
+Subject: drm/udl: make usage as a console safer
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit bcb39af4486be07e896fc374a2336bad3104ae0a upstream.
+
+Okay you don't really want to use udl devices as your console, but if
+you are unlucky enough to do so, you run into a lot of schedule while atomic
+due to printk being called from all sorts of funky places. So check if we
+are in an atomic context, and queue the damage for later, the next printk
+should cause it to appear. This isn't ideal, but it is simple, and seems to
+work okay in my testing here.
+
+(dirty area idea came from xenfb)
+
+fixes a bunch of sleeping while atomic issues running fbcon on udl devices.
+
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_drv.h |    2 +
+ drivers/gpu/drm/udl/udl_fb.c  |   44 ++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 42 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/udl/udl_drv.h
++++ b/drivers/gpu/drm/udl/udl_drv.h
+@@ -75,6 +75,8 @@ struct udl_framebuffer {
+       struct drm_framebuffer base;
+       struct udl_gem_object *obj;
+       bool active_16; /* active on the 16-bit channel */
++      int x1, y1, x2, y2; /* dirty rect */
++      spinlock_t dirty_lock;
+ };
+ #define to_udl_fb(x) container_of(x, struct udl_framebuffer, base)
+--- a/drivers/gpu/drm/udl/udl_fb.c
++++ b/drivers/gpu/drm/udl/udl_fb.c
+@@ -153,6 +153,9 @@ int udl_handle_damage(struct udl_framebu
+       struct urb *urb;
+       int aligned_x;
+       int bpp = (fb->base.bits_per_pixel / 8);
++      int x2, y2;
++      bool store_for_later = false;
++      unsigned long flags;
+       if (!fb->active_16)
+               return 0;
+@@ -169,8 +172,6 @@ int udl_handle_damage(struct udl_framebu
+               }
+       }
+-      start_cycles = get_cycles();
+-
+       aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
+       width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
+       x = aligned_x;
+@@ -180,19 +181,53 @@ int udl_handle_damage(struct udl_framebu
+           (y + height > fb->base.height))
+               return -EINVAL;
++      /* if we are in atomic just store the info
++         can't test inside spin lock */
++      if (in_atomic())
++              store_for_later = true;
++
++      x2 = x + width - 1;
++      y2 = y + height - 1;
++
++      spin_lock_irqsave(&fb->dirty_lock, flags);
++
++      if (fb->y1 < y)
++              y = fb->y1;
++      if (fb->y2 > y2)
++              y2 = fb->y2;
++      if (fb->x1 < x)
++              x = fb->x1;
++      if (fb->x2 > x2)
++              x2 = fb->x2;
++
++      if (store_for_later) {
++              fb->x1 = x;
++              fb->x2 = x2;
++              fb->y1 = y;
++              fb->y2 = y2;
++              spin_unlock_irqrestore(&fb->dirty_lock, flags);
++              return 0;
++      }
++
++      fb->x1 = fb->y1 = INT_MAX;
++      fb->x2 = fb->y2 = 0;
++
++      spin_unlock_irqrestore(&fb->dirty_lock, flags);
++      start_cycles = get_cycles();
++
+       urb = udl_get_urb(dev);
+       if (!urb)
+               return 0;
+       cmd = urb->transfer_buffer;
+-      for (i = y; i < y + height ; i++) {
++      for (i = y; i <= y2 ; i++) {
+               const int line_offset = fb->base.pitches[0] * i;
+               const int byte_offset = line_offset + (x * bpp);
+               const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
+               if (udl_render_hline(dev, bpp, &urb,
+                                    (char *) fb->obj->vmapping,
+                                    &cmd, byte_offset, dev_byte_offset,
+-                                   width * bpp,
++                                   (x2 - x + 1) * bpp,
+                                    &bytes_identical, &bytes_sent))
+                       goto error;
+       }
+@@ -434,6 +469,7 @@ udl_framebuffer_init(struct drm_device *
+ {
+       int ret;
++      spin_lock_init(&ufb->dirty_lock);
+       ufb->obj = obj;
+       ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
+       drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd);
index 3468409af89072ddc1ce8df36c1afb291d1e72ff..ce18b5c40387082d973e4ba4f694f98aa4c7d8b2 100644 (file)
@@ -61,3 +61,10 @@ sparc64-fix-gfp_flags-setting-in-tsb_grow.patch
 sparc64-handle-hugepage-tsb-being-null.patch
 sparc64-fix-tsb_grow-in-atomic-context.patch
 sparc64-fix-huge-pmd-to-pte-translation-for-sun4u-in-tlb-miss-handler.patch
+drm-radeon-dce6-fix-display-powergating.patch
+drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch
+drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch
+drm-radeon-properly-validate-the-atpx-interface.patch
+drm-udl-make-usage-as-a-console-safer.patch
+drm-udl-disable-fb_defio-by-default.patch
+vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch
diff --git a/queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch b/queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch
new file mode 100644 (file)
index 0000000..3e0e9ef
--- /dev/null
@@ -0,0 +1,103 @@
+From 2a2483072393b27f4336ab068a1f48ca19ff1c1e Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Thu, 24 Jan 2013 14:14:19 +1000
+Subject: vgacon/vt: clear buffer attributes when we load a 512 character font (v2)
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit 2a2483072393b27f4336ab068a1f48ca19ff1c1e upstream.
+
+When we switch from 256->512 byte font rendering mode, it means the
+current contents of the screen is being reinterpreted. The bit that holds
+the high bit of the 9-bit font, may have been previously set, and thus
+the new font misrenders.
+
+The problem case we see is grub2 writes spaces with the bit set, so it
+ends up with data like 0x820, which gets reinterpreted into 0x120 char
+which the font translates into G with a circumflex. This flashes up on
+screen at boot and is quite ugly.
+
+A current side effect of this patch though is that any rendering on the
+screen changes color to a slightly darker color, but at least the screen
+no longer corrupts.
+
+v2: as suggested by hpa, always clear the attribute space, whether we
+are are going to or from 512 chars.
+
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt.c            |    2 +-
+ drivers/video/console/vgacon.c |   22 +++++++++++++++-------
+ include/linux/vt_kern.h        |    1 +
+ 3 files changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -638,7 +638,7 @@ static inline void save_screen(struct vc
+  *    Redrawing of screen
+  */
+-static void clear_buffer_attributes(struct vc_data *vc)
++void clear_buffer_attributes(struct vc_data *vc)
+ {
+       unsigned short *p = (unsigned short *)vc->vc_origin;
+       int count = vc->vc_screenbuf_size / 2;
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgas
+       unsigned short video_port_status = vga_video_port_reg + 6;
+       int font_select = 0x00, beg, i;
+       char *charmap;
+-      
++      bool clear_attribs = false;
+       if (vga_video_type != VIDEO_TYPE_EGAM) {
+               charmap = (char *) VGA_MAP_MEM(colourmap, 0);
+               beg = 0x0e;
+@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgas
+       /* if 512 char mode is already enabled don't re-enable it. */
+       if ((set) && (ch512 != vga_512_chars)) {
+-              /* attribute controller */
+-              for (i = 0; i < MAX_NR_CONSOLES; i++) {
+-                      struct vc_data *c = vc_cons[i].d;
+-                      if (c && c->vc_sw == &vga_con)
+-                              c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+-              }
+               vga_512_chars = ch512;
+               /* 256-char: enable intensity bit
+                  512-char: disable intensity bit */
+@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgas
+                  it means, but it works, and it appears necessary */
+               inb_p(video_port_status);
+               vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);    
++              clear_attribs = true;
+       }
+       raw_spin_unlock_irq(&vga_lock);
++
++      if (clear_attribs) {
++              for (i = 0; i < MAX_NR_CONSOLES; i++) {
++                      struct vc_data *c = vc_cons[i].d;
++                      if (c && c->vc_sw == &vga_con) {
++                              /* force hi font mask to 0, so we always clear
++                                 the bit on either transition */
++                              c->vc_hi_font_mask = 0x00;
++                              clear_buffer_attributes(c);
++                              c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
++                      }
++              }
++      }
+       return 0;
+ }
+--- a/include/linux/vt_kern.h
++++ b/include/linux/vt_kern.h
+@@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *c
+ int con_get_cmap(unsigned char __user *cmap);
+ void scrollback(struct vc_data *vc, int lines);
+ void scrollfront(struct vc_data *vc, int lines);
++void clear_buffer_attributes(struct vc_data *vc);
+ void update_region(struct vc_data *vc, unsigned long start, int count);
+ void redraw_screen(struct vc_data *vc, int is_switch);
+ #define update_screen(x) redraw_screen(x, 0)