aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2007-10-11 23:57:15 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-22 10:01:41 -0400
commitc458473ebf31755373ca2f8063c9ec9744205924 (patch)
tree3852d3810dcaa4a1dddc684b7f735b493861e9df
parent7e7f05ca156d34b80e53105e4ef9bc1497a68439 (diff)
V4L/DVB (6329): Additional Fixes for saa7134 suspend/resume
Fixes few more problems I found in my saa7134 resume code: * Race between IRQ handler and .suspend()/.resume() functions * Removes timeout timers on active buffers - those buffers will be recaptured after resume * Adds suspend/resume for IR code - probably necessary if using polling mode * Adds #ifdef CONFIG_PM overs suspend code * Runs a quirk in set_tvnorm in suspend/resume too * Rearranges the order of calls in saa7134_resume to be exactly as in saa7134_initdev thus the card is initialized in exactly the same way * Since DMA audio capture suspend/resume isn't yet supported, avoid re-enabling it on resume for now Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c42
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c25
-rw-r--r--drivers/media/video/saa7134/saa7134.h6
5 files changed, 57 insertions, 22 deletions
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 1a4a24471f20..410242a91f43 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -429,7 +429,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
429 429
430 assert_spin_locked(&dev->slock); 430 assert_spin_locked(&dev->slock);
431 431
432 if (dev->inresume) 432 if (dev->insuspend)
433 return 0; 433 return 0;
434 434
435 /* video capture -- dma 0 + video task A */ 435 /* video capture -- dma 0 + video task A */
@@ -563,6 +563,9 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
563 unsigned long report,status; 563 unsigned long report,status;
564 int loop, handled = 0; 564 int loop, handled = 0;
565 565
566 if (dev->insuspend)
567 goto out;
568
566 for (loop = 0; loop < 10; loop++) { 569 for (loop = 0; loop < 10; loop++) {
567 report = saa_readl(SAA7134_IRQ_REPORT); 570 report = saa_readl(SAA7134_IRQ_REPORT);
568 status = saa_readl(SAA7134_IRQ_STATUS); 571 status = saa_readl(SAA7134_IRQ_STATUS);
@@ -1163,6 +1166,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1163 kfree(dev); 1166 kfree(dev);
1164} 1167}
1165 1168
1169#ifdef CONFIG_PM
1166static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) 1170static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
1167{ 1171{
1168 1172
@@ -1176,6 +1180,17 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
1176 saa_writel(SAA7134_IRQ2, 0); 1180 saa_writel(SAA7134_IRQ2, 0);
1177 saa_writel(SAA7134_MAIN_CTRL, 0); 1181 saa_writel(SAA7134_MAIN_CTRL, 0);
1178 1182
1183 synchronize_irq(pci_dev->irq);
1184 dev->insuspend = 1;
1185
1186 /* Disable timeout timers - if we have active buffers, we will
1187 fill them on resume*/
1188
1189 del_timer(&dev->video_q.timeout);
1190 del_timer(&dev->vbi_q.timeout);
1191 del_timer(&dev->ts_q.timeout);
1192 saa7134_ir_stop(dev);
1193
1179 pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); 1194 pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
1180 pci_save_state(pci_dev); 1195 pci_save_state(pci_dev);
1181 1196
@@ -1194,24 +1209,27 @@ static int saa7134_resume(struct pci_dev *pci_dev)
1194 /* Do things that are done in saa7134_initdev , 1209 /* Do things that are done in saa7134_initdev ,
1195 except of initializing memory structures.*/ 1210 except of initializing memory structures.*/
1196 1211
1197 dev->inresume = 1;
1198 saa7134_board_init1(dev); 1212 saa7134_board_init1(dev);
1199 1213
1214 /* saa7134_hwinit1 */
1200 if (saa7134_boards[dev->board].video_out) 1215 if (saa7134_boards[dev->board].video_out)
1201 saa7134_videoport_init(dev); 1216 saa7134_videoport_init(dev);
1202
1203 if (card_has_mpeg(dev)) 1217 if (card_has_mpeg(dev))
1204 saa7134_ts_init_hw(dev); 1218 saa7134_ts_init_hw(dev);
1205 1219 if (dev->remote)
1220 saa7134_ir_start(dev, dev->remote);
1206 saa7134_hw_enable1(dev); 1221 saa7134_hw_enable1(dev);
1207 saa7134_set_decoder(dev); 1222
1208 saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); 1223
1209 saa7134_board_init2(dev); 1224 saa7134_board_init2(dev);
1210 saa7134_hw_enable2(dev);
1211 1225
1226 /*saa7134_hwinit2*/
1227 saa7134_set_tvnorm_hw(dev);
1212 saa7134_tvaudio_setmute(dev); 1228 saa7134_tvaudio_setmute(dev);
1213 saa7134_tvaudio_setvolume(dev, dev->ctl_volume); 1229 saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
1230 saa7134_tvaudio_do_scan(dev);
1214 saa7134_enable_i2s(dev); 1231 saa7134_enable_i2s(dev);
1232 saa7134_hw_enable2(dev);
1215 1233
1216 /*resume unfinished buffer(s)*/ 1234 /*resume unfinished buffer(s)*/
1217 spin_lock_irqsave(&dev->slock, flags); 1235 spin_lock_irqsave(&dev->slock, flags);
@@ -1219,13 +1237,19 @@ static int saa7134_resume(struct pci_dev *pci_dev)
1219 saa7134_buffer_requeue(dev, &dev->vbi_q); 1237 saa7134_buffer_requeue(dev, &dev->vbi_q);
1220 saa7134_buffer_requeue(dev, &dev->ts_q); 1238 saa7134_buffer_requeue(dev, &dev->ts_q);
1221 1239
1240 /* FIXME: Disable DMA audio sound - temporary till proper support
1241 is implemented*/
1242
1243 dev->dmasound.dma_running = 0;
1244
1222 /* start DMA now*/ 1245 /* start DMA now*/
1223 dev->inresume = 0; 1246 dev->insuspend = 0;
1224 saa7134_set_dmabits(dev); 1247 saa7134_set_dmabits(dev);
1225 spin_unlock_irqrestore(&dev->slock, flags); 1248 spin_unlock_irqrestore(&dev->slock, flags);
1226 1249
1227 return 0; 1250 return 0;
1228} 1251}
1252#endif
1229 1253
1230/* ----------------------------------------------------------- */ 1254/* ----------------------------------------------------------- */
1231 1255
@@ -1262,8 +1286,10 @@ static struct pci_driver saa7134_pci_driver = {
1262 .id_table = saa7134_pci_tbl, 1286 .id_table = saa7134_pci_tbl,
1263 .probe = saa7134_initdev, 1287 .probe = saa7134_initdev,
1264 .remove = __devexit_p(saa7134_finidev), 1288 .remove = __devexit_p(saa7134_finidev),
1289#ifdef CONFIG_PM
1265 .suspend = saa7134_suspend, 1290 .suspend = saa7134_suspend,
1266 .resume = saa7134_resume 1291 .resume = saa7134_resume
1292#endif
1267}; 1293};
1268 1294
1269static int saa7134_init(void) 1295static int saa7134_init(void)
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 80d2644f765a..d4907ce4e51f 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -159,7 +159,7 @@ static void saa7134_input_timer(unsigned long data)
159 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); 159 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
160} 160}
161 161
162static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) 162void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
163{ 163{
164 if (ir->polling) { 164 if (ir->polling) {
165 setup_timer(&ir->timer, saa7134_input_timer, 165 setup_timer(&ir->timer, saa7134_input_timer,
@@ -182,7 +182,7 @@ static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
182 } 182 }
183} 183}
184 184
185static void saa7134_ir_stop(struct saa7134_dev *dev) 185void saa7134_ir_stop(struct saa7134_dev *dev)
186{ 186{
187 if (dev->remote->polling) 187 if (dev->remote->polling)
188 del_timer_sync(&dev->remote->timer); 188 del_timer_sync(&dev->remote->timer);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 1b9e39a5ea47..976318d50828 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -231,7 +231,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
231 } 231 }
232 232
233 if (dev->hw_mute == mute && 233 if (dev->hw_mute == mute &&
234 dev->hw_input == in && !dev->inresume) { 234 dev->hw_input == in && !dev->insuspend) {
235 dprintk("mute/input: nothing to do [mute=%d,input=%s]\n", 235 dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
236 mute,in->name); 236 mute,in->name);
237 return; 237 return;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 2b0897770531..3b9ffb4b648a 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -560,15 +560,8 @@ void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
560 560
561 dev->crop_current = dev->crop_defrect; 561 dev->crop_current = dev->crop_defrect;
562 562
563 saa7134_set_decoder(dev); 563 saa7134_set_tvnorm_hw(dev);
564 564
565 if (card_in(dev, dev->ctl_input).tv) {
566 if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
567 && ((card(dev).tuner_config == 1)
568 || (card(dev).tuner_config == 2)))
569 saa7134_set_gpio(dev, 22, 5);
570 saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
571 }
572} 565}
573 566
574static void video_mux(struct saa7134_dev *dev, int input) 567static void video_mux(struct saa7134_dev *dev, int input)
@@ -579,7 +572,8 @@ static void video_mux(struct saa7134_dev *dev, int input)
579 saa7134_tvaudio_setinput(dev, &card_in(dev, input)); 572 saa7134_tvaudio_setinput(dev, &card_in(dev, input));
580} 573}
581 574
582void saa7134_set_decoder(struct saa7134_dev *dev) 575
576static void saa7134_set_decoder(struct saa7134_dev *dev)
583{ 577{
584 int luma_control, sync_control, mux; 578 int luma_control, sync_control, mux;
585 579
@@ -630,6 +624,19 @@ void saa7134_set_decoder(struct saa7134_dev *dev)
630 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); 624 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
631} 625}
632 626
627void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
628{
629 saa7134_set_decoder(dev);
630
631 if (card_in(dev, dev->ctl_input).tv) {
632 if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
633 && ((card(dev).tuner_config == 1)
634 || (card(dev).tuner_config == 2)))
635 saa7134_set_gpio(dev, 22, 5);
636 saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
637 }
638}
639
633static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) 640static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
634{ 641{
635 static const struct { 642 static const struct {
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 28ec6804bd5d..fe0a8439b878 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -524,7 +524,7 @@ struct saa7134_dev {
524 unsigned int hw_mute; 524 unsigned int hw_mute;
525 int last_carrier; 525 int last_carrier;
526 int nosignal; 526 int nosignal;
527 unsigned int inresume; 527 unsigned int insuspend;
528 528
529 /* SAA7134_MPEG_* */ 529 /* SAA7134_MPEG_* */
530 struct saa7134_ts ts; 530 struct saa7134_ts ts;
@@ -632,7 +632,7 @@ extern struct video_device saa7134_radio_template;
632 632
633void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm); 633void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
634int saa7134_videoport_init(struct saa7134_dev *dev); 634int saa7134_videoport_init(struct saa7134_dev *dev);
635void saa7134_set_decoder(struct saa7134_dev *dev); 635void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
636 636
637int saa7134_common_ioctl(struct saa7134_dev *dev, 637int saa7134_common_ioctl(struct saa7134_dev *dev,
638 unsigned int cmd, void *arg); 638 unsigned int cmd, void *arg);
@@ -706,6 +706,8 @@ int saa7134_input_init1(struct saa7134_dev *dev);
706void saa7134_input_fini(struct saa7134_dev *dev); 706void saa7134_input_fini(struct saa7134_dev *dev);
707void saa7134_input_irq(struct saa7134_dev *dev); 707void saa7134_input_irq(struct saa7134_dev *dev);
708void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); 708void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
709void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
710void saa7134_ir_stop(struct saa7134_dev *dev);
709 711
710 712
711/* 713/*