diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 24 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-firmware.c | 76 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.c | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 41 |
8 files changed, 142 insertions, 15 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 3737797f20ea..90daa6e751d8 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1444,6 +1444,7 @@ EXPORT_SYMBOL(ivtv_udma_unmap); | |||
1444 | EXPORT_SYMBOL(ivtv_udma_alloc); | 1444 | EXPORT_SYMBOL(ivtv_udma_alloc); |
1445 | EXPORT_SYMBOL(ivtv_udma_prepare); | 1445 | EXPORT_SYMBOL(ivtv_udma_prepare); |
1446 | EXPORT_SYMBOL(ivtv_init_on_first_open); | 1446 | EXPORT_SYMBOL(ivtv_init_on_first_open); |
1447 | EXPORT_SYMBOL(ivtv_firmware_check); | ||
1447 | 1448 | ||
1448 | module_init(module_start); | 1449 | module_init(module_start); |
1449 | module_exit(module_cleanup); | 1450 | module_exit(module_cleanup); |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index c038dc8beb3c..bd084df4448a 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -737,6 +737,7 @@ struct ivtv { | |||
737 | struct v4l2_rect osd_rect; /* current OSD position and size */ | 737 | struct v4l2_rect osd_rect; /* current OSD position and size */ |
738 | struct v4l2_rect main_rect; /* current Main window position and size */ | 738 | struct v4l2_rect main_rect; /* current Main window position and size */ |
739 | struct osd_info *osd_info; /* ivtvfb private OSD info */ | 739 | struct osd_info *osd_info; /* ivtvfb private OSD info */ |
740 | void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */ | ||
740 | }; | 741 | }; |
741 | 742 | ||
742 | static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) | 743 | static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev) |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 3fb21e1406a1..a6a2cdb81566 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -536,8 +536,12 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed) | |||
536 | return -EBUSY; | 536 | return -EBUSY; |
537 | } | 537 | } |
538 | rc = ivtv_start_v4l2_decode_stream(s, 0); | 538 | rc = ivtv_start_v4l2_decode_stream(s, 0); |
539 | if (rc < 0) | 539 | if (rc < 0) { |
540 | return rc; | 540 | if (rc == -EAGAIN) |
541 | rc = ivtv_start_v4l2_decode_stream(s, 0); | ||
542 | if (rc < 0) | ||
543 | return rc; | ||
544 | } | ||
541 | } | 545 | } |
542 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) | 546 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) |
543 | return ivtv_set_speed(itv, speed); | 547 | return ivtv_set_speed(itv, speed); |
@@ -926,19 +930,21 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
926 | IVTV_DEBUG_FILE("open %s\n", s->name); | 930 | IVTV_DEBUG_FILE("open %s\n", s->name); |
927 | 931 | ||
928 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 932 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
933 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ | ||
929 | if (ivtv_fw_debug) { | 934 | if (ivtv_fw_debug) { |
930 | IVTV_WARN("Opening %s with dead firmware lockout disabled\n", | 935 | IVTV_WARN("Opening %s with dead firmware lockout disabled\n", |
931 | video_device_node_name(vdev)); | 936 | video_device_node_name(vdev)); |
932 | IVTV_WARN("Selected firmware errors will be ignored\n"); | 937 | IVTV_WARN("Selected firmware errors will be ignored\n"); |
933 | } | 938 | } else { |
934 | |||
935 | /* Unless ivtv_fw_debug is set, error out if firmware dead. */ | ||
936 | if (ivtv_firmware_check(itv, "ivtv_serialized_open") && !ivtv_fw_debug) | ||
937 | return -EIO; | ||
938 | #else | 939 | #else |
939 | if (ivtv_firmware_check(itv, "ivtv_serialized_open")) | 940 | if (1) { |
940 | return -EIO; | ||
941 | #endif | 941 | #endif |
942 | res = ivtv_firmware_check(itv, "ivtv_serialized_open"); | ||
943 | if (res == -EAGAIN) | ||
944 | res = ivtv_firmware_check(itv, "ivtv_serialized_open"); | ||
945 | if (res < 0) | ||
946 | return -EIO; | ||
947 | } | ||
942 | 948 | ||
943 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG && | 949 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG && |
944 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) | 950 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) |
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index efb288d34ca3..d8bf2b01729d 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c | |||
@@ -23,7 +23,10 @@ | |||
23 | #include "ivtv-mailbox.h" | 23 | #include "ivtv-mailbox.h" |
24 | #include "ivtv-firmware.h" | 24 | #include "ivtv-firmware.h" |
25 | #include "ivtv-yuv.h" | 25 | #include "ivtv-yuv.h" |
26 | #include "ivtv-ioctl.h" | ||
27 | #include "ivtv-cards.h" | ||
26 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
29 | #include <media/saa7127.h> | ||
27 | 30 | ||
28 | #define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE | 31 | #define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE |
29 | #define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 | 32 | #define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 |
@@ -272,6 +275,58 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv) | |||
272 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); | 275 | ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); |
273 | } | 276 | } |
274 | 277 | ||
278 | /* Try to restart the card & restore previous settings */ | ||
279 | int ivtv_firmware_restart(struct ivtv *itv) | ||
280 | { | ||
281 | int rc = 0; | ||
282 | v4l2_std_id std; | ||
283 | struct ivtv_open_id fh; | ||
284 | fh.itv = itv; | ||
285 | |||
286 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) | ||
287 | /* Display test image during restart */ | ||
288 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, | ||
289 | SAA7127_INPUT_TYPE_TEST_IMAGE, | ||
290 | itv->card->video_outputs[itv->active_output].video_output, | ||
291 | 0); | ||
292 | |||
293 | mutex_lock(&itv->udma.lock); | ||
294 | |||
295 | rc = ivtv_firmware_init(itv); | ||
296 | if (rc) { | ||
297 | mutex_unlock(&itv->udma.lock); | ||
298 | return rc; | ||
299 | } | ||
300 | |||
301 | /* Allow settings to reload */ | ||
302 | ivtv_mailbox_cache_invalidate(itv); | ||
303 | |||
304 | /* Restore video standard */ | ||
305 | std = itv->std; | ||
306 | itv->std = 0; | ||
307 | ivtv_s_std(NULL, &fh, &std); | ||
308 | |||
309 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
310 | ivtv_init_mpeg_decoder(itv); | ||
311 | |||
312 | /* Restore framebuffer if active */ | ||
313 | if (itv->ivtvfb_restore) | ||
314 | itv->ivtvfb_restore(itv); | ||
315 | |||
316 | /* Restore alpha settings */ | ||
317 | ivtv_set_osd_alpha(itv); | ||
318 | |||
319 | /* Restore normal output */ | ||
320 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, | ||
321 | SAA7127_INPUT_TYPE_NORMAL, | ||
322 | itv->card->video_outputs[itv->active_output].video_output, | ||
323 | 0); | ||
324 | } | ||
325 | |||
326 | mutex_unlock(&itv->udma.lock); | ||
327 | return rc; | ||
328 | } | ||
329 | |||
275 | /* Check firmware running state. The checks fall through | 330 | /* Check firmware running state. The checks fall through |
276 | allowing multiple failures to be logged. */ | 331 | allowing multiple failures to be logged. */ |
277 | int ivtv_firmware_check(struct ivtv *itv, char *where) | 332 | int ivtv_firmware_check(struct ivtv *itv, char *where) |
@@ -315,5 +370,26 @@ int ivtv_firmware_check(struct ivtv *itv, char *where) | |||
315 | } | 370 | } |
316 | } | 371 | } |
317 | 372 | ||
373 | /* If something failed & currently idle, try to reload */ | ||
374 | if (res && !atomic_read(&itv->capturing) && | ||
375 | !atomic_read(&itv->decoding)) { | ||
376 | IVTV_INFO("Detected in %s that firmware had failed - " | ||
377 | "Reloading\n", where); | ||
378 | res = ivtv_firmware_restart(itv); | ||
379 | /* | ||
380 | * Even if restarted ok, still signal a problem had occured. | ||
381 | * The caller can come through this function again to check | ||
382 | * if things are really ok after the restart. | ||
383 | */ | ||
384 | if (!res) { | ||
385 | IVTV_INFO("Firmware restart okay\n"); | ||
386 | res = -EAGAIN; | ||
387 | } else { | ||
388 | IVTV_INFO("Firmware restart failed\n"); | ||
389 | } | ||
390 | } else if (res) { | ||
391 | res = -EIO; | ||
392 | } | ||
393 | |||
318 | return res; | 394 | return res; |
319 | } | 395 | } |
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 84577f6f41a2..e3ce96763785 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c | |||
@@ -377,3 +377,11 @@ void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, | |||
377 | for (i = 0; i < argc; i++, p++) | 377 | for (i = 0; i < argc; i++, p++) |
378 | data[i] = readl(p); | 378 | data[i] = readl(p); |
379 | } | 379 | } |
380 | |||
381 | /* Wipe api cache */ | ||
382 | void ivtv_mailbox_cache_invalidate(struct ivtv *itv) | ||
383 | { | ||
384 | int i; | ||
385 | for (i = 0; i < 256; i++) | ||
386 | itv->api_cache[i].last_jiffies = 0; | ||
387 | } | ||
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h index 8247662c928e..2c834d2cb56f 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.h +++ b/drivers/media/video/ivtv/ivtv-mailbox.h | |||
@@ -30,5 +30,6 @@ int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); | |||
30 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); | 30 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); |
31 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); | 31 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); |
32 | int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); | 32 | int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]); |
33 | void ivtv_mailbox_cache_invalidate(struct ivtv *itv); | ||
33 | 34 | ||
34 | #endif | 35 | #endif |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index f0dd011a2ccc..55df4190c28d 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -676,10 +676,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
676 | ivtv_msleep_timeout(10, 0); | 676 | ivtv_msleep_timeout(10, 0); |
677 | 677 | ||
678 | /* Known failure point for firmware, so check */ | 678 | /* Known failure point for firmware, so check */ |
679 | if (ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream") < 0) | 679 | return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream"); |
680 | return -EIO; | ||
681 | |||
682 | return 0; | ||
683 | } | 680 | } |
684 | 681 | ||
685 | int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) | 682 | int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) |
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 9ff3425891ed..2c2d862ca89f 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include "ivtv-i2c.h" | 53 | #include "ivtv-i2c.h" |
54 | #include "ivtv-udma.h" | 54 | #include "ivtv-udma.h" |
55 | #include "ivtv-mailbox.h" | 55 | #include "ivtv-mailbox.h" |
56 | #include "ivtv-firmware.h" | ||
56 | 57 | ||
57 | /* card parameters */ | 58 | /* card parameters */ |
58 | static int ivtvfb_card_id = -1; | 59 | static int ivtvfb_card_id = -1; |
@@ -178,6 +179,12 @@ struct osd_info { | |||
178 | struct fb_info ivtvfb_info; | 179 | struct fb_info ivtvfb_info; |
179 | struct fb_var_screeninfo ivtvfb_defined; | 180 | struct fb_var_screeninfo ivtvfb_defined; |
180 | struct fb_fix_screeninfo ivtvfb_fix; | 181 | struct fb_fix_screeninfo ivtvfb_fix; |
182 | |||
183 | /* Used for a warm start */ | ||
184 | struct fb_var_screeninfo fbvar_cur; | ||
185 | int blank_cur; | ||
186 | u32 palette_cur[256]; | ||
187 | u32 pan_cur; | ||
181 | }; | 188 | }; |
182 | 189 | ||
183 | struct ivtv_osd_coords { | 190 | struct ivtv_osd_coords { |
@@ -199,6 +206,7 @@ static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase, | |||
199 | u32 data[CX2341X_MBOX_MAX_DATA]; | 206 | u32 data[CX2341X_MBOX_MAX_DATA]; |
200 | int rc; | 207 | int rc; |
201 | 208 | ||
209 | ivtv_firmware_check(itv, "ivtvfb_get_framebuffer"); | ||
202 | rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0); | 210 | rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0); |
203 | *fbbase = data[0]; | 211 | *fbbase = data[0]; |
204 | *fblength = data[1]; | 212 | *fblength = data[1]; |
@@ -581,8 +589,10 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
581 | ivtv_window.height = var->yres; | 589 | ivtv_window.height = var->yres; |
582 | 590 | ||
583 | /* Minimum margin cannot be 0, as X won't allow such a mode */ | 591 | /* Minimum margin cannot be 0, as X won't allow such a mode */ |
584 | if (!var->upper_margin) var->upper_margin++; | 592 | if (!var->upper_margin) |
585 | if (!var->left_margin) var->left_margin++; | 593 | var->upper_margin++; |
594 | if (!var->left_margin) | ||
595 | var->left_margin++; | ||
586 | ivtv_window.top = var->upper_margin - 1; | 596 | ivtv_window.top = var->upper_margin - 1; |
587 | ivtv_window.left = var->left_margin - 1; | 597 | ivtv_window.left = var->left_margin - 1; |
588 | 598 | ||
@@ -595,6 +605,9 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
595 | /* Force update of yuv registers */ | 605 | /* Force update of yuv registers */ |
596 | itv->yuv_info.yuv_forced_update = 1; | 606 | itv->yuv_info.yuv_forced_update = 1; |
597 | 607 | ||
608 | /* Keep a copy of these settings */ | ||
609 | memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur)); | ||
610 | |||
598 | IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n", | 611 | IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n", |
599 | var->xres, var->yres, | 612 | var->xres, var->yres, |
600 | var->xres_virtual, var->yres_virtual, | 613 | var->xres_virtual, var->yres_virtual, |
@@ -829,6 +842,8 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf | |||
829 | itv->yuv_info.osd_y_pan = var->yoffset; | 842 | itv->yuv_info.osd_y_pan = var->yoffset; |
830 | /* Force update of yuv registers */ | 843 | /* Force update of yuv registers */ |
831 | itv->yuv_info.yuv_forced_update = 1; | 844 | itv->yuv_info.yuv_forced_update = 1; |
845 | /* Remember this value */ | ||
846 | itv->osd_info->pan_cur = osd_pan_index; | ||
832 | return 0; | 847 | return 0; |
833 | } | 848 | } |
834 | 849 | ||
@@ -842,6 +857,7 @@ static int ivtvfb_set_par(struct fb_info *info) | |||
842 | rc = ivtvfb_set_var(itv, &info->var); | 857 | rc = ivtvfb_set_var(itv, &info->var); |
843 | ivtvfb_pan_display(&info->var, info); | 858 | ivtvfb_pan_display(&info->var, info); |
844 | ivtvfb_get_fix(itv, &info->fix); | 859 | ivtvfb_get_fix(itv, &info->fix); |
860 | ivtv_firmware_check(itv, "ivtvfb_set_par"); | ||
845 | return rc; | 861 | return rc; |
846 | } | 862 | } |
847 | 863 | ||
@@ -859,6 +875,7 @@ static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
859 | if (info->var.bits_per_pixel <= 8) { | 875 | if (info->var.bits_per_pixel <= 8) { |
860 | write_reg(regno, 0x02a30); | 876 | write_reg(regno, 0x02a30); |
861 | write_reg(color, 0x02a34); | 877 | write_reg(color, 0x02a34); |
878 | itv->osd_info->palette_cur[regno] = color; | ||
862 | return 0; | 879 | return 0; |
863 | } | 880 | } |
864 | if (regno >= 16) | 881 | if (regno >= 16) |
@@ -911,6 +928,7 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info) | |||
911 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); | 928 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); |
912 | break; | 929 | break; |
913 | } | 930 | } |
931 | itv->osd_info->blank_cur = blank_mode; | ||
914 | return 0; | 932 | return 0; |
915 | } | 933 | } |
916 | 934 | ||
@@ -929,6 +947,21 @@ static struct fb_ops ivtvfb_ops = { | |||
929 | .fb_blank = ivtvfb_blank, | 947 | .fb_blank = ivtvfb_blank, |
930 | }; | 948 | }; |
931 | 949 | ||
950 | /* Restore hardware after firmware restart */ | ||
951 | static void ivtvfb_restore(struct ivtv *itv) | ||
952 | { | ||
953 | struct osd_info *oi = itv->osd_info; | ||
954 | int i; | ||
955 | |||
956 | ivtvfb_set_var(itv, &oi->fbvar_cur); | ||
957 | ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info); | ||
958 | for (i = 0; i < 256; i++) { | ||
959 | write_reg(i, 0x02a30); | ||
960 | write_reg(oi->palette_cur[i], 0x02a34); | ||
961 | } | ||
962 | write_reg(oi->pan_cur, 0x02a0c); | ||
963 | } | ||
964 | |||
932 | /* Initialization */ | 965 | /* Initialization */ |
933 | 966 | ||
934 | 967 | ||
@@ -1192,6 +1225,9 @@ static int ivtvfb_init_card(struct ivtv *itv) | |||
1192 | /* Enable the osd */ | 1225 | /* Enable the osd */ |
1193 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); | 1226 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); |
1194 | 1227 | ||
1228 | /* Enable restart */ | ||
1229 | itv->ivtvfb_restore = ivtvfb_restore; | ||
1230 | |||
1195 | /* Allocate DMA */ | 1231 | /* Allocate DMA */ |
1196 | ivtv_udma_alloc(itv); | 1232 | ivtv_udma_alloc(itv); |
1197 | return 0; | 1233 | return 0; |
@@ -1226,6 +1262,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) | |||
1226 | return 0; | 1262 | return 0; |
1227 | } | 1263 | } |
1228 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); | 1264 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); |
1265 | itv->ivtvfb_restore = NULL; | ||
1229 | ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); | 1266 | ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); |
1230 | ivtvfb_release_buffers(itv); | 1267 | ivtvfb_release_buffers(itv); |
1231 | itv->osd_video_pbase = 0; | 1268 | itv->osd_video_pbase = 0; |