diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2007-10-11 23:57:15 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-22 10:01:41 -0400 |
commit | c458473ebf31755373ca2f8063c9ec9744205924 (patch) | |
tree | 3852d3810dcaa4a1dddc684b7f735b493861e9df /drivers/media/video/saa7134/saa7134-core.c | |
parent | 7e7f05ca156d34b80e53105e4ef9bc1497a68439 (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>
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-core.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 1a4a24471f2..410242a91f4 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 | ||
1166 | static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) | 1170 | static 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 | ||
1269 | static int saa7134_init(void) | 1295 | static int saa7134_init(void) |