summary refs log tree commit diff
path: root/drivers/media
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2007-10-12 00:57:15 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-22 12:01:41 -0200
commitc458473ebf31755373ca2f8063c9ec9744205924 (patch)
tree3852d3810dcaa4a1dddc684b7f735b493861e9df /drivers/media
parent7e7f05ca156d34b80e53105e4ef9bc1497a68439 (diff)
downloadlinux-c458473ebf31755373ca2f8063c9ec9744205924.tar.gz
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>
Diffstat (limited to 'drivers/media')
-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)
 
 	assert_spin_locked(&dev->slock);
 
-	if (dev->inresume)
+	if (dev->insuspend)
 		return 0;
 
 	/* video capture -- dma 0 + video task A */
@@ -563,6 +563,9 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
 	unsigned long report,status;
 	int loop, handled = 0;
 
+	if (dev->insuspend)
+		goto out;
+
 	for (loop = 0; loop < 10; loop++) {
 		report = saa_readl(SAA7134_IRQ_REPORT);
 		status = saa_readl(SAA7134_IRQ_STATUS);
@@ -1163,6 +1166,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 	kfree(dev);
 }
 
+#ifdef CONFIG_PM
 static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 {
 
@@ -1176,6 +1180,17 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 	saa_writel(SAA7134_IRQ2, 0);
 	saa_writel(SAA7134_MAIN_CTRL, 0);
 
+	synchronize_irq(pci_dev->irq);
+	dev->insuspend = 1;
+
+	/* Disable timeout timers - if we have active buffers, we will
+	   fill them on resume*/
+
+	del_timer(&dev->video_q.timeout);
+	del_timer(&dev->vbi_q.timeout);
+	del_timer(&dev->ts_q.timeout);
+	saa7134_ir_stop(dev);
+
 	pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
 	pci_save_state(pci_dev);
 
@@ -1194,24 +1209,27 @@ static int saa7134_resume(struct pci_dev *pci_dev)
 	/* Do things that are done in saa7134_initdev ,
 		except of initializing memory structures.*/
 
-	dev->inresume = 1;
 	saa7134_board_init1(dev);
 
+	/* saa7134_hwinit1 */
 	if (saa7134_boards[dev->board].video_out)
 		saa7134_videoport_init(dev);
-
 	if (card_has_mpeg(dev))
 		saa7134_ts_init_hw(dev);
-
+	if (dev->remote)
+		saa7134_ir_start(dev, dev->remote);
 	saa7134_hw_enable1(dev);
-	saa7134_set_decoder(dev);
-	saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+
+
 	saa7134_board_init2(dev);
-	saa7134_hw_enable2(dev);
 
+	/*saa7134_hwinit2*/
+	saa7134_set_tvnorm_hw(dev);
 	saa7134_tvaudio_setmute(dev);
 	saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
+	saa7134_tvaudio_do_scan(dev);
 	saa7134_enable_i2s(dev);
+	saa7134_hw_enable2(dev);
 
 	/*resume unfinished buffer(s)*/
 	spin_lock_irqsave(&dev->slock, flags);
@@ -1219,13 +1237,19 @@ static int saa7134_resume(struct pci_dev *pci_dev)
 	saa7134_buffer_requeue(dev, &dev->vbi_q);
 	saa7134_buffer_requeue(dev, &dev->ts_q);
 
+	/* FIXME: Disable DMA audio sound - temporary till proper support
+		  is implemented*/
+
+	dev->dmasound.dma_running = 0;
+
 	/* start DMA now*/
-	dev->inresume = 0;
+	dev->insuspend = 0;
 	saa7134_set_dmabits(dev);
 	spin_unlock_irqrestore(&dev->slock, flags);
 
 	return 0;
 }
+#endif
 
 /* ----------------------------------------------------------- */
 
@@ -1262,8 +1286,10 @@ static struct pci_driver saa7134_pci_driver = {
 	.id_table = saa7134_pci_tbl,
 	.probe    = saa7134_initdev,
 	.remove   = __devexit_p(saa7134_finidev),
+#ifdef CONFIG_PM
 	.suspend  = saa7134_suspend,
 	.resume   = saa7134_resume
+#endif
 };
 
 static 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)
 	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 }
 
-static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
 {
 	if (ir->polling) {
 		setup_timer(&ir->timer, saa7134_input_timer,
@@ -182,7 +182,7 @@ static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
 	}
 }
 
-static void saa7134_ir_stop(struct saa7134_dev *dev)
+void saa7134_ir_stop(struct saa7134_dev *dev)
 {
 	if (dev->remote->polling)
 		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)
 	}
 
 	if (dev->hw_mute  == mute &&
-		dev->hw_input == in && !dev->inresume) {
+		dev->hw_input == in && !dev->insuspend) {
 		dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
 			mute,in->name);
 		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)
 
 	dev->crop_current = dev->crop_defrect;
 
-	saa7134_set_decoder(dev);
+	saa7134_set_tvnorm_hw(dev);
 
-	if (card_in(dev, dev->ctl_input).tv) {
-		if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
-				&& ((card(dev).tuner_config == 1)
-				||  (card(dev).tuner_config == 2)))
-			saa7134_set_gpio(dev, 22, 5);
-		saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
-	}
 }
 
 static void video_mux(struct saa7134_dev *dev, int input)
@@ -579,7 +572,8 @@ static void video_mux(struct saa7134_dev *dev, int input)
 	saa7134_tvaudio_setinput(dev, &card_in(dev, input));
 }
 
-void saa7134_set_decoder(struct saa7134_dev *dev)
+
+static void saa7134_set_decoder(struct saa7134_dev *dev)
 {
 	int luma_control, sync_control, mux;
 
@@ -630,6 +624,19 @@ void saa7134_set_decoder(struct saa7134_dev *dev)
 	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
 }
 
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
+{
+	saa7134_set_decoder(dev);
+
+	if (card_in(dev, dev->ctl_input).tv) {
+		if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
+				&& ((card(dev).tuner_config == 1)
+				||  (card(dev).tuner_config == 2)))
+			saa7134_set_gpio(dev, 22, 5);
+		saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+	}
+}
+
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
 {
 	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 {
 	unsigned int               hw_mute;
 	int                        last_carrier;
 	int                        nosignal;
-	unsigned int               inresume;
+	unsigned int               insuspend;
 
 	/* SAA7134_MPEG_* */
 	struct saa7134_ts          ts;
@@ -632,7 +632,7 @@ extern struct video_device saa7134_radio_template;
 
 void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
 int saa7134_videoport_init(struct saa7134_dev *dev);
-void saa7134_set_decoder(struct saa7134_dev *dev);
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
 
 int saa7134_common_ioctl(struct saa7134_dev *dev,
 			 unsigned int cmd, void *arg);
@@ -706,6 +706,8 @@ int  saa7134_input_init1(struct saa7134_dev *dev);
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
+void saa7134_ir_stop(struct saa7134_dev *dev);
 
 
 /*