aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-22 22:20:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-22 22:20:22 -0400
commitad792f4f46e12bae58298fc64f5139b99664a773 (patch)
tree3d20c3a0840b00deb95fe62fdff1bc6e59eb37fe /drivers/media/video/ivtv
parent3650b0a304663d98a63c68f9020eb1ded477989e (diff)
parentf40aa808bad19a079a0e122e326d6970df141afb (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (37 commits) V4L/DVB (6382): saa7134: fix NULL dereference at suspend time for cards without IR receiver V4L/DVB (6380): ivtvfb: Removal of the 'osd_compat' module option V4L/DVB (6379): patch which improves GotView Saa7135 remote control V4L/DVB (6378b): Updates info about the removal of V4L1 at feature-removal-schedule.txt V4L/DVB (6378a): Removal of VIDIOC_[G|S]_MPEGCOMP from feature-removal-schedule.txt V4L/DVB (6378): DiB0700-device: Using 1.10 firmware V4L/DVB (6357): pvrusb2: Improve encoder chip health tracking V4L/DVB (6356): "while (!ca->wakeup)" breaks the CAM initialisation V4L/DVB (6352): ir-kbd-i2c: Missing break statement V4L/DVB (6350): V4L: possible leak in em28xx_init_isoc V4L/DVB (6348): ivtv: undo video mute when closing the radio V4L/DVB (6347): ivtv: fix video mute when radio is used V4L/DVB (6346): ivtvfb: YUV output size fix when ivtvfb is not loaded V4L/DVB (6345): ivtvfb: YUV handling of an image which is not visible in the display area V4L/DVB (6343): ivtvfb: check return value of unregister_framebuffer V4L/DVB (6342): ivtv: fix circular locking (bug 9037) V4L/DVB (6341): ivtv: fix resizing MPEG1 streams V4L/DVB (6340): ivtvfb: screen mode change sometimes goes wrong V4L/DVB (6339): ivtv: set the video color to black instead of green when capturing from the radio V4L/DVB (6338): ivtv: fix incorrect EBUSY return ...
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c13
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c116
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c160
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h1
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c92
8 files changed, 200 insertions, 202 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index fd7a932e1d33..6d2dd8764f81 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1003,8 +1003,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1003 1003
1004 IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); 1004 IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
1005 1005
1006 mutex_lock(&itv->serialize_lock);
1007
1008 /* PCI Device Setup */ 1006 /* PCI Device Setup */
1009 if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { 1007 if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
1010 if (retval == -EIO) 1008 if (retval == -EIO)
@@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1064 IVTV_DEBUG_INFO("activating i2c...\n"); 1062 IVTV_DEBUG_INFO("activating i2c...\n");
1065 if (init_ivtv_i2c(itv)) { 1063 if (init_ivtv_i2c(itv)) {
1066 IVTV_ERR("Could not initialize i2c\n"); 1064 IVTV_ERR("Could not initialize i2c\n");
1067 goto free_irq; 1065 goto free_io;
1068 } 1066 }
1069 1067
1070 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); 1068 IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
@@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1176 IVTV_ERR("Failed to register irq %d\n", retval); 1174 IVTV_ERR("Failed to register irq %d\n", retval);
1177 goto free_streams; 1175 goto free_streams;
1178 } 1176 }
1179 mutex_unlock(&itv->serialize_lock); 1177 retval = ivtv_streams_register(itv);
1178 if (retval) {
1179 IVTV_ERR("Error %d registering devices\n", retval);
1180 goto free_irq;
1181 }
1180 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); 1182 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
1181 return 0; 1183 return 0;
1182 1184
@@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1195 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1197 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1196 free_workqueue: 1198 free_workqueue:
1197 destroy_workqueue(itv->irq_work_queues); 1199 destroy_workqueue(itv->irq_work_queues);
1198 mutex_unlock(&itv->serialize_lock);
1199 err: 1200 err:
1200 if (retval == 0) 1201 if (retval == 0)
1201 retval = -ENODEV; 1202 retval = -ENODEV;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index da50fa4a72a5..a200a8a95a2d 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -822,6 +822,11 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
822 crystal_freq.flags = 0; 822 crystal_freq.flags = 0;
823 ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); 823 ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
824 } 824 }
825 if (atomic_read(&itv->capturing) > 0) {
826 /* Undo video mute */
827 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
828 itv->params.video_mute | (itv->params.video_mute_yuv << 8));
829 }
825 /* Done! Unmute and continue. */ 830 /* Done! Unmute and continue. */
826 ivtv_unmute(itv); 831 ivtv_unmute(itv);
827 ivtv_release_stream(s); 832 ivtv_release_stream(s);
@@ -892,6 +897,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
892 if (atomic_read(&itv->capturing) > 0) { 897 if (atomic_read(&itv->capturing) > 0) {
893 /* switching to radio while capture is 898 /* switching to radio while capture is
894 in progress is not polite */ 899 in progress is not polite */
900 ivtv_release_stream(s);
895 kfree(item); 901 kfree(item);
896 return -EBUSY; 902 return -EBUSY;
897 } 903 }
@@ -947,7 +953,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
947 if (itv == NULL) { 953 if (itv == NULL) {
948 /* Couldn't find a device registered 954 /* Couldn't find a device registered
949 on that minor, shouldn't happen! */ 955 on that minor, shouldn't happen! */
950 IVTV_WARN("No ivtv device found on minor %d\n", minor); 956 printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
951 return -ENXIO; 957 return -ENXIO;
952 } 958 }
953 959
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 206eee7542db..fd6826f472e3 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -555,6 +555,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
555 555
556 /* set window size */ 556 /* set window size */
557 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 557 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
558 struct cx2341x_mpeg_params *p = &itv->params;
558 int w = fmt->fmt.pix.width; 559 int w = fmt->fmt.pix.width;
559 int h = fmt->fmt.pix.height; 560 int h = fmt->fmt.pix.height;
560 561
@@ -566,17 +567,19 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
566 fmt->fmt.pix.width = w; 567 fmt->fmt.pix.width = w;
567 fmt->fmt.pix.height = h; 568 fmt->fmt.pix.height = h;
568 569
569 if (!set_fmt || (itv->params.width == w && itv->params.height == h)) 570 if (!set_fmt || (p->width == w && p->height == h))
570 return 0; 571 return 0;
571 if (atomic_read(&itv->capturing) > 0) 572 if (atomic_read(&itv->capturing) > 0)
572 return -EBUSY; 573 return -EBUSY;
573 574
574 itv->params.width = w; 575 p->width = w;
575 itv->params.height = h; 576 p->height = h;
576 if (w != 720 || h != (itv->is_50hz ? 576 : 480)) 577 if (w != 720 || h != (itv->is_50hz ? 576 : 480))
577 itv->params.video_temporal_filter = 0; 578 p->video_temporal_filter = 0;
578 else 579 else
579 itv->params.video_temporal_filter = 8; 580 p->video_temporal_filter = 8;
581 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
582 fmt->fmt.pix.width /= 2;
580 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 583 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
581 return ivtv_get_fmt(itv, streamtype, fmt); 584 return ivtv_get_fmt(itv, streamtype, fmt);
582 } 585 }
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index fd135985e70f..aa03e61ef310 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -166,10 +166,9 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
166 ivtv_queue_init(&s->q_io); 166 ivtv_queue_init(&s->q_io);
167} 167}
168 168
169static int ivtv_reg_dev(struct ivtv *itv, int type) 169static int ivtv_prep_dev(struct ivtv *itv, int type)
170{ 170{
171 struct ivtv_stream *s = &itv->streams[type]; 171 struct ivtv_stream *s = &itv->streams[type];
172 int vfl_type = ivtv_stream_info[type].vfl_type;
173 int minor_offset = ivtv_stream_info[type].minor_offset; 172 int minor_offset = ivtv_stream_info[type].minor_offset;
174 int minor; 173 int minor;
175 174
@@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
187 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 186 if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
188 return 0; 187 return 0;
189 188
190 if (minor_offset >= 0) 189 /* card number + user defined offset + device offset */
191 /* card number + user defined offset + device offset */ 190 minor = itv->num + ivtv_first_minor + minor_offset;
192 minor = itv->num + ivtv_first_minor + minor_offset;
193 else
194 minor = -1;
195 191
196 /* User explicitly selected 0 buffers for these streams, so don't 192 /* User explicitly selected 0 buffers for these streams, so don't
197 create them. */ 193 create them. */
198 if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE && 194 if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
199 itv->options.kilobytes[type] == 0) { 195 itv->options.kilobytes[type] == 0) {
200 IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); 196 IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
201 return 0; 197 return 0;
@@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
223 s->v4l2dev->fops = ivtv_stream_info[type].fops; 219 s->v4l2dev->fops = ivtv_stream_info[type].fops;
224 s->v4l2dev->release = video_device_release; 220 s->v4l2dev->release = video_device_release;
225 221
226 if (minor >= 0) { 222 return 0;
227 /* Register device. First try the desired minor, then any free one. */ 223}
228 if (video_register_device(s->v4l2dev, vfl_type, minor) && 224
229 video_register_device(s->v4l2dev, vfl_type, -1)) { 225/* Initialize v4l2 variables and prepare v4l2 devices */
230 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", 226int ivtv_streams_setup(struct ivtv *itv)
231 s->name, minor); 227{
232 video_device_release(s->v4l2dev); 228 int type;
233 s->v4l2dev = NULL; 229
234 return -ENOMEM; 230 /* Setup V4L2 Devices */
235 } 231 for (type = 0; type < IVTV_MAX_STREAMS; type++) {
232 /* Prepare device */
233 if (ivtv_prep_dev(itv, type))
234 break;
235
236 if (itv->streams[type].v4l2dev == NULL)
237 continue;
238
239 /* Allocate Stream */
240 if (ivtv_stream_alloc(&itv->streams[type]))
241 break;
236 } 242 }
237 else { 243 if (type == IVTV_MAX_STREAMS)
238 /* Don't register a 'hidden' stream (OSD) */
239 IVTV_INFO("Created framebuffer stream for %s\n", s->name);
240 return 0; 244 return 0;
245
246 /* One or more streams could not be initialized. Clean 'em all up. */
247 ivtv_streams_cleanup(itv);
248 return -ENOMEM;
249}
250
251static int ivtv_reg_dev(struct ivtv *itv, int type)
252{
253 struct ivtv_stream *s = &itv->streams[type];
254 int vfl_type = ivtv_stream_info[type].vfl_type;
255 int minor;
256
257 if (s->v4l2dev == NULL)
258 return 0;
259
260 minor = s->v4l2dev->minor;
261 /* Register device. First try the desired minor, then any free one. */
262 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
263 video_register_device(s->v4l2dev, vfl_type, -1)) {
264 IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
265 s->name, minor);
266 video_device_release(s->v4l2dev);
267 s->v4l2dev = NULL;
268 return -ENOMEM;
241 } 269 }
242 270
243 switch (vfl_type) { 271 switch (vfl_type) {
@@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
262 return 0; 290 return 0;
263} 291}
264 292
265/* Initialize v4l2 variables and register v4l2 devices */ 293/* Register v4l2 devices */
266int ivtv_streams_setup(struct ivtv *itv) 294int ivtv_streams_register(struct ivtv *itv)
267{ 295{
268 int type; 296 int type;
297 int err = 0;
269 298
270 /* Setup V4L2 Devices */ 299 /* Register V4L2 devices */
271 for (type = 0; type < IVTV_MAX_STREAMS; type++) { 300 for (type = 0; type < IVTV_MAX_STREAMS; type++)
272 /* Register Device */ 301 err |= ivtv_reg_dev(itv, type);
273 if (ivtv_reg_dev(itv, type))
274 break;
275
276 if (itv->streams[type].v4l2dev == NULL)
277 continue;
278 302
279 /* Allocate Stream */ 303 if (err == 0)
280 if (ivtv_stream_alloc(&itv->streams[type]))
281 break;
282 }
283 if (type == IVTV_MAX_STREAMS) {
284 return 0; 304 return 0;
285 }
286 305
287 /* One or more streams could not be initialized. Clean 'em all up. */ 306 /* One or more streams could not be initialized. Clean 'em all up. */
288 ivtv_streams_cleanup(itv); 307 ivtv_streams_cleanup(itv);
@@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv)
303 continue; 322 continue;
304 323
305 ivtv_stream_free(&itv->streams[type]); 324 ivtv_stream_free(&itv->streams[type]);
306 /* Free Device */ 325 /* Unregister device */
307 if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */ 326 video_unregister_device(vdev);
308 video_device_release(vdev);
309 else /* All others, just unregister. */
310 video_unregister_device(vdev);
311 } 327 }
312} 328}
313 329
@@ -425,6 +441,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
425{ 441{
426 u32 data[CX2341X_MBOX_MAX_DATA]; 442 u32 data[CX2341X_MBOX_MAX_DATA];
427 struct ivtv *itv = s->itv; 443 struct ivtv *itv = s->itv;
444 struct cx2341x_mpeg_params *p = &itv->params;
428 int captype = 0, subtype = 0; 445 int captype = 0, subtype = 0;
429 int enable_passthrough = 0; 446 int enable_passthrough = 0;
430 447
@@ -445,7 +462,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
445 } 462 }
446 itv->mpg_data_received = itv->vbi_data_inserted = 0; 463 itv->mpg_data_received = itv->vbi_data_inserted = 0;
447 itv->dualwatch_jiffies = jiffies; 464 itv->dualwatch_jiffies = jiffies;
448 itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300; 465 itv->dualwatch_stereo_mode = p->audio_properties & 0x0300;
449 itv->search_pack_header = 0; 466 itv->search_pack_header = 0;
450 break; 467 break;
451 468
@@ -477,9 +494,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
477 s->subtype = subtype; 494 s->subtype = subtype;
478 s->buffers_stolen = 0; 495 s->buffers_stolen = 0;
479 496
480 /* mute/unmute video */
481 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0);
482
483 /* Clear Streamoff flags in case left from last capture */ 497 /* Clear Streamoff flags in case left from last capture */
484 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); 498 clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
485 499
@@ -536,7 +550,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
536 itv->pgm_info_offset, itv->pgm_info_num); 550 itv->pgm_info_offset, itv->pgm_info_num);
537 551
538 /* Setup API for Stream */ 552 /* Setup API for Stream */
539 cx2341x_update(itv, ivtv_api_func, NULL, &itv->params); 553 cx2341x_update(itv, ivtv_api_func, NULL, p);
554
555 /* mute if capturing radio */
556 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
557 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
558 1 | (p->video_mute_yuv << 8));
540 } 559 }
541 560
542 /* Vsync Setup */ 561 /* Vsync Setup */
@@ -585,6 +604,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
585{ 604{
586 u32 data[CX2341X_MBOX_MAX_DATA]; 605 u32 data[CX2341X_MBOX_MAX_DATA];
587 struct ivtv *itv = s->itv; 606 struct ivtv *itv = s->itv;
607 struct cx2341x_mpeg_params *p = &itv->params;
588 int datatype; 608 int datatype;
589 609
590 if (s->v4l2dev == NULL) 610 if (s->v4l2dev == NULL)
@@ -623,7 +643,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
623 break; 643 break;
624 } 644 }
625 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, 645 if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
626 itv->params.width, itv->params.height, itv->params.audio_properties)) { 646 p->width, p->height, p->audio_properties)) {
627 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); 647 IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
628 } 648 }
629 return 0; 649 return 0;
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 8f5f5b1c7c89..3d76a415fbd8 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -22,6 +22,7 @@
22#define IVTV_STREAMS_H 22#define IVTV_STREAMS_H
23 23
24int ivtv_streams_setup(struct ivtv *itv); 24int ivtv_streams_setup(struct ivtv *itv);
25int ivtv_streams_register(struct ivtv *itv);
25void ivtv_streams_cleanup(struct ivtv *itv); 26void ivtv_streams_cleanup(struct ivtv *itv);
26 27
27/* Capture related */ 28/* Capture related */
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index e2288f224ab6..9091c4837bbc 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -710,7 +710,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
710 710
711 /* If there's nothing to safe to display, we may as well stop now */ 711 /* If there's nothing to safe to display, we may as well stop now */
712 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { 712 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
713 return 0; 713 return IVTV_YUV_UPDATE_INVALID;
714 } 714 }
715 715
716 /* Ensure video remains inside OSD area */ 716 /* Ensure video remains inside OSD area */
@@ -791,7 +791,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
791 791
792 /* Check again. If there's nothing to safe to display, stop now */ 792 /* Check again. If there's nothing to safe to display, stop now */
793 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { 793 if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
794 return 0; 794 return IVTV_YUV_UPDATE_INVALID;
795 } 795 }
796 796
797 /* Both x offset & width are linked, so they have to be done together */ 797 /* Both x offset & width are linked, so they have to be done together */
@@ -840,110 +840,118 @@ void ivtv_yuv_work_handler (struct ivtv *itv)
840 if (!(yuv_update = ivtv_yuv_window_setup (itv, &window))) 840 if (!(yuv_update = ivtv_yuv_window_setup (itv, &window)))
841 return; 841 return;
842 842
843 /* Update horizontal settings */ 843 if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
844 if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) 844 write_reg(0x01008080, 0x2898);
845 ivtv_yuv_handle_horizontal(itv, &window); 845 } else if (yuv_update) {
846 write_reg(0x00108080, 0x2898);
846 847
847 if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) 848 if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
848 ivtv_yuv_handle_vertical(itv, &window); 849 ivtv_yuv_handle_horizontal(itv, &window);
850
851 if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
852 ivtv_yuv_handle_vertical(itv, &window);
853 }
849 854
850 memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info)); 855 memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info));
851} 856}
852 857
853static void ivtv_yuv_init (struct ivtv *itv) 858static void ivtv_yuv_init (struct ivtv *itv)
854{ 859{
860 struct yuv_playback_info *yi = &itv->yuv_info;
861
855 IVTV_DEBUG_YUV("ivtv_yuv_init\n"); 862 IVTV_DEBUG_YUV("ivtv_yuv_init\n");
856 863
857 /* Take a snapshot of the current register settings */ 864 /* Take a snapshot of the current register settings */
858 itv->yuv_info.reg_2834 = read_reg(0x02834); 865 yi->reg_2834 = read_reg(0x02834);
859 itv->yuv_info.reg_2838 = read_reg(0x02838); 866 yi->reg_2838 = read_reg(0x02838);
860 itv->yuv_info.reg_283c = read_reg(0x0283c); 867 yi->reg_283c = read_reg(0x0283c);
861 itv->yuv_info.reg_2840 = read_reg(0x02840); 868 yi->reg_2840 = read_reg(0x02840);
862 itv->yuv_info.reg_2844 = read_reg(0x02844); 869 yi->reg_2844 = read_reg(0x02844);
863 itv->yuv_info.reg_2848 = read_reg(0x02848); 870 yi->reg_2848 = read_reg(0x02848);
864 itv->yuv_info.reg_2854 = read_reg(0x02854); 871 yi->reg_2854 = read_reg(0x02854);
865 itv->yuv_info.reg_285c = read_reg(0x0285c); 872 yi->reg_285c = read_reg(0x0285c);
866 itv->yuv_info.reg_2864 = read_reg(0x02864); 873 yi->reg_2864 = read_reg(0x02864);
867 itv->yuv_info.reg_2870 = read_reg(0x02870); 874 yi->reg_2870 = read_reg(0x02870);
868 itv->yuv_info.reg_2874 = read_reg(0x02874); 875 yi->reg_2874 = read_reg(0x02874);
869 itv->yuv_info.reg_2898 = read_reg(0x02898); 876 yi->reg_2898 = read_reg(0x02898);
870 itv->yuv_info.reg_2890 = read_reg(0x02890); 877 yi->reg_2890 = read_reg(0x02890);
871 878
872 itv->yuv_info.reg_289c = read_reg(0x0289c); 879 yi->reg_289c = read_reg(0x0289c);
873 itv->yuv_info.reg_2918 = read_reg(0x02918); 880 yi->reg_2918 = read_reg(0x02918);
874 itv->yuv_info.reg_291c = read_reg(0x0291c); 881 yi->reg_291c = read_reg(0x0291c);
875 itv->yuv_info.reg_2920 = read_reg(0x02920); 882 yi->reg_2920 = read_reg(0x02920);
876 itv->yuv_info.reg_2924 = read_reg(0x02924); 883 yi->reg_2924 = read_reg(0x02924);
877 itv->yuv_info.reg_2928 = read_reg(0x02928); 884 yi->reg_2928 = read_reg(0x02928);
878 itv->yuv_info.reg_292c = read_reg(0x0292c); 885 yi->reg_292c = read_reg(0x0292c);
879 itv->yuv_info.reg_2930 = read_reg(0x02930); 886 yi->reg_2930 = read_reg(0x02930);
880 itv->yuv_info.reg_2934 = read_reg(0x02934); 887 yi->reg_2934 = read_reg(0x02934);
881 itv->yuv_info.reg_2938 = read_reg(0x02938); 888 yi->reg_2938 = read_reg(0x02938);
882 itv->yuv_info.reg_293c = read_reg(0x0293c); 889 yi->reg_293c = read_reg(0x0293c);
883 itv->yuv_info.reg_2940 = read_reg(0x02940); 890 yi->reg_2940 = read_reg(0x02940);
884 itv->yuv_info.reg_2944 = read_reg(0x02944); 891 yi->reg_2944 = read_reg(0x02944);
885 itv->yuv_info.reg_2948 = read_reg(0x02948); 892 yi->reg_2948 = read_reg(0x02948);
886 itv->yuv_info.reg_294c = read_reg(0x0294c); 893 yi->reg_294c = read_reg(0x0294c);
887 itv->yuv_info.reg_2950 = read_reg(0x02950); 894 yi->reg_2950 = read_reg(0x02950);
888 itv->yuv_info.reg_2954 = read_reg(0x02954); 895 yi->reg_2954 = read_reg(0x02954);
889 itv->yuv_info.reg_2958 = read_reg(0x02958); 896 yi->reg_2958 = read_reg(0x02958);
890 itv->yuv_info.reg_295c = read_reg(0x0295c); 897 yi->reg_295c = read_reg(0x0295c);
891 itv->yuv_info.reg_2960 = read_reg(0x02960); 898 yi->reg_2960 = read_reg(0x02960);
892 itv->yuv_info.reg_2964 = read_reg(0x02964); 899 yi->reg_2964 = read_reg(0x02964);
893 itv->yuv_info.reg_2968 = read_reg(0x02968); 900 yi->reg_2968 = read_reg(0x02968);
894 itv->yuv_info.reg_296c = read_reg(0x0296c); 901 yi->reg_296c = read_reg(0x0296c);
895 itv->yuv_info.reg_2970 = read_reg(0x02970); 902 yi->reg_2970 = read_reg(0x02970);
896 903
897 itv->yuv_info.v_filter_1 = -1; 904 yi->v_filter_1 = -1;
898 itv->yuv_info.v_filter_2 = -1; 905 yi->v_filter_2 = -1;
899 itv->yuv_info.h_filter = -1; 906 yi->h_filter = -1;
900 907
901 /* Set some valid size info */ 908 /* Set some valid size info */
902 itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF; 909 yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
903 itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; 910 yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
904 911
905 /* Bit 2 of reg 2878 indicates current decoder output format 912 /* Bit 2 of reg 2878 indicates current decoder output format
906 0 : NTSC 1 : PAL */ 913 0 : NTSC 1 : PAL */
907 if (read_reg(0x2878) & 4) 914 if (read_reg(0x2878) & 4)
908 itv->yuv_info.decode_height = 576; 915 yi->decode_height = 576;
909 else 916 else
910 itv->yuv_info.decode_height = 480; 917 yi->decode_height = 480;
911 918
912 /* If no visible size set, assume full size */ 919 if (!itv->osd_info) {
913 if (!itv->yuv_info.osd_vis_w) 920 yi->osd_vis_w = 720 - yi->osd_x_offset;
914 itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset; 921 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
915
916 if (!itv->yuv_info.osd_vis_h) {
917 itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
918 } else { 922 } else {
919 /* If output video standard has changed, requested height may 923 /* If no visible size set, assume full size */
920 not be legal */ 924 if (!yi->osd_vis_w)
921 if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) { 925 yi->osd_vis_w = 720 - yi->osd_x_offset;
922 IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", 926
923 itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset, 927 if (!yi->osd_vis_h)
924 itv->yuv_info.decode_height); 928 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
925 itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; 929 else {
930 /* If output video standard has changed, requested height may
931 not be legal */
932 if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
933 IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
934 yi->osd_vis_h + yi->osd_y_offset,
935 yi->decode_height);
936 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
937 }
926 } 938 }
927 } 939 }
928 940
929 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ 941 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
930 itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL); 942 yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL);
931 if (itv->yuv_info.blanking_ptr) { 943 if (yi->blanking_ptr)
932 itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE); 944 yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
933 }
934 else { 945 else {
935 itv->yuv_info.blanking_dmaptr = 0; 946 yi->blanking_dmaptr = 0;
936 IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n"); 947 IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
937 } 948 }
938 949
939 IVTV_DEBUG_WARN("Enable video output\n");
940 write_reg_sync(0x00108080, 0x2898);
941
942 /* Enable YUV decoder output */ 950 /* Enable YUV decoder output */
943 write_reg_sync(0x01, IVTV_REG_VDM); 951 write_reg_sync(0x01, IVTV_REG_VDM);
944 952
945 set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); 953 set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
946 atomic_set(&itv->yuv_info.next_dma_frame,0); 954 atomic_set(&yi->next_dma_frame, 0);
947} 955}
948 956
949int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) 957int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
index f7215eeca018..3b966f0a204a 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ b/drivers/media/video/ivtv/ivtv-yuv.h
@@ -34,6 +34,7 @@
34 34
35#define IVTV_YUV_UPDATE_HORIZONTAL 0x01 35#define IVTV_YUV_UPDATE_HORIZONTAL 0x01
36#define IVTV_YUV_UPDATE_VERTICAL 0x02 36#define IVTV_YUV_UPDATE_VERTICAL 0x02
37#define IVTV_YUV_UPDATE_INVALID 0x04
37 38
38extern const u32 yuv_offset[4]; 39extern const u32 yuv_offset[4];
39 40
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 9684048fe56c..52ffd154a3d8 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -55,7 +55,6 @@
55static int ivtvfb_card_id = -1; 55static int ivtvfb_card_id = -1;
56static int ivtvfb_debug = 0; 56static int ivtvfb_debug = 0;
57static int osd_laced; 57static int osd_laced;
58static int osd_compat;
59static int osd_depth; 58static int osd_depth;
60static int osd_upper; 59static int osd_upper;
61static int osd_left; 60static int osd_left;
@@ -65,7 +64,6 @@ static int osd_xres;
65module_param(ivtvfb_card_id, int, 0444); 64module_param(ivtvfb_card_id, int, 0444);
66module_param_named(debug,ivtvfb_debug, int, 0644); 65module_param_named(debug,ivtvfb_debug, int, 0644);
67module_param(osd_laced, bool, 0444); 66module_param(osd_laced, bool, 0444);
68module_param(osd_compat, bool, 0444);
69module_param(osd_depth, int, 0444); 67module_param(osd_depth, int, 0444);
70module_param(osd_upper, int, 0444); 68module_param(osd_upper, int, 0444);
71module_param(osd_left, int, 0444); 69module_param(osd_left, int, 0444);
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug,
80 "Debug level (bitmask). Default: errors only\n" 78 "Debug level (bitmask). Default: errors only\n"
81 "\t\t\t(debug = 3 gives full debugging)"); 79 "\t\t\t(debug = 3 gives full debugging)");
82 80
83MODULE_PARM_DESC(osd_compat,
84 "Compatibility mode - Display size is locked (use for old X drivers)\n"
85 "\t\t\t0=off\n"
86 "\t\t\t1=on\n"
87 "\t\t\tdefault off");
88
89/* Why upper, left, xres, yres, depth, laced ? To match terminology used 81/* Why upper, left, xres, yres, depth, laced ? To match terminology used
90 by fbset. 82 by fbset.
91 Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ 83 Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
@@ -166,9 +158,6 @@ struct osd_info {
166 unsigned long fb_end_aligned_physaddr; 158 unsigned long fb_end_aligned_physaddr;
167#endif 159#endif
168 160
169 /* Current osd mode */
170 int osd_mode;
171
172 /* Store the buffer offset */ 161 /* Store the buffer offset */
173 int set_osd_coords_x; 162 int set_osd_coords_x;
174 int set_osd_coords_y; 163 int set_osd_coords_y;
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
470 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); 459 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
471 } 460 }
472 461
473 /* Change osd mode if needed. 462 /* Set video mode. Although rare, the display can become scrambled even
474 Although rare, things can go wrong. The extra mode 463 if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
475 change seems to help... */ 464 if (osd_mode != -1) {
476 if (osd_mode != -1 && osd_mode != oi->osd_mode) {
477 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 465 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
478 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); 466 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
479 oi->osd_mode = osd_mode;
480 } 467 }
481 468
482 oi->bits_per_pixel = var->bits_per_pixel; 469 oi->bits_per_pixel = var->bits_per_pixel;
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
579 osd_height_limit = 480; 566 osd_height_limit = 480;
580 } 567 }
581 568
582 /* Check the bits per pixel */
583 if (osd_compat) {
584 if (var->bits_per_pixel != 32) {
585 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
586 return -EINVAL;
587 }
588 }
589
590 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { 569 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
591 var->transp.offset = 24; 570 var->transp.offset = 24;
592 var->transp.length = 8; 571 var->transp.length = 8;
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
638 } 617 }
639 618
640 /* Check the resolution */ 619 /* Check the resolution */
641 if (osd_compat) { 620 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
642 if (var->xres != oi->ivtvfb_defined.xres || 621 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
643 var->yres != oi->ivtvfb_defined.yres || 622 var->xres, var->yres);
644 var->xres_virtual != oi->ivtvfb_defined.xres_virtual || 623 return -EINVAL;
645 var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
646 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
647 var->xres, var->yres, var->xres_virtual, var->yres_virtual);
648 return -EINVAL;
649 }
650 } 624 }
651 else {
652 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
653 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
654 var->xres, var->yres);
655 return -EINVAL;
656 }
657 625
658 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ 626 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
659 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || 627 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
660 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || 628 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
661 var->xres_virtual < var->xres || 629 var->xres_virtual < var->xres ||
662 var->yres_virtual < var->yres) { 630 var->yres_virtual < var->yres) {
663 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", 631 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
664 var->xres_virtual, var->yres_virtual); 632 var->xres_virtual, var->yres_virtual);
665 return -EINVAL; 633 return -EINVAL;
666 }
667 } 634 }
668 635
669 /* Some extra checks if in 8 bit mode */ 636 /* Some extra checks if in 8 bit mode */
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
877 844
878 /* Color mode */ 845 /* Color mode */
879 846
880 if (osd_compat) osd_depth = 32; 847 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
881 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8; 848 osd_depth = 8;
882 oi->bits_per_pixel = osd_depth; 849 oi->bits_per_pixel = osd_depth;
883 oi->bytes_per_pixel = oi->bits_per_pixel / 8; 850 oi->bytes_per_pixel = oi->bits_per_pixel / 8;
884 851
885 /* Invalidate current osd mode to force a mode switch later */
886 oi->osd_mode = -1;
887
888 /* Horizontal size & position */ 852 /* Horizontal size & position */
889 853
890 if (osd_xres > 720) osd_xres = 720; 854 if (osd_xres > 720)
855 osd_xres = 720;
891 856
892 /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ 857 /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
893 if (osd_depth == 8) 858 if (osd_depth == 8)
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
895 else if (osd_depth == 16) 860 else if (osd_depth == 16)
896 osd_xres &= ~1; 861 osd_xres &= ~1;
897 862
898 if (osd_xres) 863 start_window.width = osd_xres ? osd_xres : 640;
899 start_window.width = osd_xres;
900 else
901 start_window.width = osd_compat ? 720: 640;
902 864
903 /* Check horizontal start (osd_left). */ 865 /* Check horizontal start (osd_left). */
904 if (osd_left && osd_left + start_window.width > 721) { 866 if (osd_left && osd_left + start_window.width > 721) {
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
921 if (osd_yres > max_height) 883 if (osd_yres > max_height)
922 osd_yres = max_height; 884 osd_yres = max_height;
923 885
924 if (osd_yres) 886 start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
925 start_window.height = osd_yres;
926 else
927 start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
928 887
929 /* Check vertical start (osd_upper). */ 888 /* Check vertical start (osd_upper). */
930 if (osd_upper + start_window.height > max_height + 1) { 889 if (osd_upper + start_window.height > max_height + 1) {
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv)
1127 /* Enable the osd */ 1086 /* Enable the osd */
1128 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); 1087 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1129 1088
1130 /* Note if we're running in compatibility mode */
1131 if (osd_compat)
1132 IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
1133
1134 /* Allocate DMA */ 1089 /* Allocate DMA */
1135 ivtv_udma_alloc(itv); 1090 ivtv_udma_alloc(itv);
1136 return 0; 1091 return 0;
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void)
1177 for (i = 0; i < ivtv_cards_active; i++) { 1132 for (i = 0; i < ivtv_cards_active; i++) {
1178 itv = ivtv_cards[i]; 1133 itv = ivtv_cards[i];
1179 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { 1134 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
1135 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1136 IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
1137 return;
1138 }
1180 IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); 1139 IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
1181 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); 1140 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
1182 unregister_framebuffer(&itv->osd_info->ivtvfb_info);
1183 ivtvfb_release_buffers(itv); 1141 ivtvfb_release_buffers(itv);
1184 itv->osd_video_pbase = 0; 1142 itv->osd_video_pbase = 0;
1185 } 1143 }