diff options
author | Ian Armstrong <ian@iarmst.demon.co.uk> | 2009-09-22 19:47:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:57 -0400 |
commit | 2ddce3fd0acbdc1be684fb5f919ae3d2e9518aac (patch) | |
tree | 9868c190efdf179e3f9939f53f2273c3640d2102 /drivers/video/console/fbcon.c | |
parent | a690606d1f54845b018d033ac32e91df25cb2680 (diff) |
fbcon: only unbind from console if successfully registered
Attempting to unload a framebuffer module calls unregister_framebuffer()
which in turn gets fbcon to release it. If fbcon has no framebuffers
linked to a console, it will also unbind itself from the console driver.
However, if fbcon never registered itself as a console driver, the unbind
will fail causing the framebuffer device entry to persist. In most cases
this failure will result in an oops when attempting to access the now
non-existent device.
This patch ensures that the fbcon unbind request will succeed even if a
bind was never done. It tracks if a successful bind ever occurred & will
only attempt to unbind if needed. If there never was a bind, it simply
returns with no error.
Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/console/fbcon.c')
-rw-r--r-- | drivers/video/console/fbcon.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 4bee7c2e6313..5a686cea23f4 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -114,6 +114,7 @@ static int last_fb_vc = MAX_NR_CONSOLES - 1; | |||
114 | static int fbcon_is_default = 1; | 114 | static int fbcon_is_default = 1; |
115 | static int fbcon_has_exited; | 115 | static int fbcon_has_exited; |
116 | static int primary_device = -1; | 116 | static int primary_device = -1; |
117 | static int fbcon_has_console_bind; | ||
117 | 118 | ||
118 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY | 119 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY |
119 | static int map_override; | 120 | static int map_override; |
@@ -544,6 +545,8 @@ static int fbcon_takeover(int show_logo) | |||
544 | con2fb_map[i] = -1; | 545 | con2fb_map[i] = -1; |
545 | } | 546 | } |
546 | info_idx = -1; | 547 | info_idx = -1; |
548 | } else { | ||
549 | fbcon_has_console_bind = 1; | ||
547 | } | 550 | } |
548 | 551 | ||
549 | return err; | 552 | return err; |
@@ -2949,6 +2952,10 @@ static int fbcon_unbind(void) | |||
2949 | 2952 | ||
2950 | ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, | 2953 | ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, |
2951 | fbcon_is_default); | 2954 | fbcon_is_default); |
2955 | |||
2956 | if (!ret) | ||
2957 | fbcon_has_console_bind = 0; | ||
2958 | |||
2952 | return ret; | 2959 | return ret; |
2953 | } | 2960 | } |
2954 | #else | 2961 | #else |
@@ -2962,6 +2969,9 @@ static int fbcon_fb_unbind(int idx) | |||
2962 | { | 2969 | { |
2963 | int i, new_idx = -1, ret = 0; | 2970 | int i, new_idx = -1, ret = 0; |
2964 | 2971 | ||
2972 | if (!fbcon_has_console_bind) | ||
2973 | return 0; | ||
2974 | |||
2965 | for (i = first_fb_vc; i <= last_fb_vc; i++) { | 2975 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
2966 | if (con2fb_map[i] != idx && | 2976 | if (con2fb_map[i] != idx && |
2967 | con2fb_map[i] != -1) { | 2977 | con2fb_map[i] != -1) { |