diff options
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/Kconfig | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 54 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 21 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 14 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-firmware.c | 29 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-gpio.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-i2c.c | 20 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 4 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 47 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.c | 33 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 45 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.c | 31 |
12 files changed, 165 insertions, 149 deletions
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 1aaeaa02f15..e43beb2c9cb 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,7 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL + select I2C_ALGOBIT select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM @@ -16,11 +17,11 @@ config VIDEO_IVTV select VIDEO_UPD64031A select VIDEO_UPD64083 ---help--- - This is a video4linux driver for Conexant cx23416 or cx23416 based + This is a video4linux driver for Conexant cx23416 or cx23415 based PCI personal video recorder devices. This is used in devices such as the Hauppauge PVR-150/250/350/500 - cards. + cards. There is a driver homepage at <http://www.ivtvdriver.org>. To compile this driver as a module, choose M here: the module will be called ivtv. diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index efc66355339..d73d433a4ff 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -56,7 +56,6 @@ #include "ivtv-gpio.h" #include "ivtv-yuv.h" -#include <linux/vermagic.h> #include <media/tveeprom.h> #include <media/v4l2-chip-ident.h> @@ -181,7 +180,7 @@ MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); MODULE_PARM_DESC(debug, "Debug level (bitmask). Default: errors only\n" - "\t\t\t(debug = 511 gives full debugging)"); + "\t\t\t(debug = 1023 gives full debugging)"); MODULE_PARM_DESC(ivtv_pci_latency, "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" "\t\t\tDefault: Yes"); @@ -276,9 +275,10 @@ int ivtv_waitq(wait_queue_head_t *waitq) } /* Generic utility functions */ -int ivtv_sleep_timeout(int timeout, int intr) +int ivtv_msleep_timeout(unsigned int msecs, int intr) { int ret; + int timeout = msecs_to_jiffies(msecs); do { set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); @@ -339,6 +339,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) /* In a few cases the PCI subsystem IDs do not correctly identify the card. A better method is to check the model number from the eeprom instead. */ + case 30012 ... 30039: /* Low profile PVR250 */ case 32000 ... 32999: case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */ case 48400 ... 48599: @@ -426,7 +427,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) { itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0; if (itv->options.newi2c) { - IVTV_INFO("reopen i2c bus for IR-blaster support\n"); + IVTV_INFO("Reopen i2c bus for IR-blaster support\n"); exit_ivtv_i2c(itv); init_ivtv_i2c(itv); } @@ -622,6 +623,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ + mutex_init(&itv->serialize_lock); mutex_init(&itv->i2c_bus_lock); mutex_init(&itv->udma.lock); @@ -949,7 +951,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, /* Make sure we've got a place for this card */ if (ivtv_cards_active == IVTV_MAX_CARDS) { - printk(KERN_ERR "ivtv: Maximum number of cards detected (%d).\n", + printk(KERN_ERR "ivtv: Maximum number of cards detected (%d)\n", ivtv_cards_active); spin_unlock(&ivtv_cards_lock); return -ENOMEM; @@ -964,9 +966,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, itv->dev = dev; itv->num = ivtv_cards_active++; snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num); - if (itv->num) { - printk(KERN_INFO "ivtv: ====================== NEXT CARD ======================\n"); - } + IVTV_INFO("Initializing card #%d\n", itv->num); spin_unlock(&ivtv_cards_lock); @@ -1213,7 +1213,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, if (itv->has_cx23415) ivtv_set_osd_alpha(itv); - IVTV_INFO("Initialized %s, card #%d\n", itv->card_name, itv->num); + IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); return 0; @@ -1246,15 +1246,15 @@ static void ivtv_remove(struct pci_dev *pci_dev) { struct ivtv *itv = pci_get_drvdata(pci_dev); - IVTV_DEBUG_INFO("Removing Card #%d.\n", itv->num); + IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num); /* Stop all captures */ - IVTV_DEBUG_INFO(" Stopping all streams.\n"); + IVTV_DEBUG_INFO("Stopping all streams\n"); if (atomic_read(&itv->capturing) > 0) ivtv_stop_all_captures(itv); /* Stop all decoding */ - IVTV_DEBUG_INFO(" Stopping decoding.\n"); + IVTV_DEBUG_INFO("Stopping decoding\n"); if (atomic_read(&itv->decoding) > 0) { int type; @@ -1267,33 +1267,30 @@ static void ivtv_remove(struct pci_dev *pci_dev) } /* Interrupts */ - IVTV_DEBUG_INFO(" Disabling interrupts.\n"); + IVTV_DEBUG_INFO("Disabling interrupts\n"); ivtv_set_irq_mask(itv, 0xffffffff); del_timer_sync(&itv->dma_timer); /* Stop all Work Queues */ - IVTV_DEBUG_INFO(" Stop Work Queues.\n"); + IVTV_DEBUG_INFO("Stop Work Queues\n"); flush_workqueue(itv->irq_work_queues); destroy_workqueue(itv->irq_work_queues); - IVTV_DEBUG_INFO(" Stopping Firmware.\n"); + IVTV_DEBUG_INFO("Stopping Firmware\n"); ivtv_halt_firmware(itv); - IVTV_DEBUG_INFO(" Unregistering v4l devices.\n"); + IVTV_DEBUG_INFO("Unregistering v4l devices\n"); ivtv_streams_cleanup(itv); - IVTV_DEBUG_INFO(" Freeing dma resources.\n"); + IVTV_DEBUG_INFO("Freeing dma resources\n"); ivtv_udma_free(itv); exit_ivtv_i2c(itv); - IVTV_DEBUG_INFO(" Releasing irq.\n"); + IVTV_DEBUG_INFO(" Releasing irq\n"); free_irq(itv->dev->irq, (void *)itv); + ivtv_iounmap(itv); - if (itv->dev) { - ivtv_iounmap(itv); - } - - IVTV_DEBUG_INFO(" Releasing mem.\n"); + IVTV_DEBUG_INFO(" Releasing mem\n"); release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (itv->has_cx23415) @@ -1314,28 +1311,27 @@ static struct pci_driver ivtv_pci_driver = { static int module_start(void) { - printk(KERN_INFO "ivtv: ==================== START INIT IVTV ====================\n"); - printk(KERN_INFO "ivtv: version %s (" VERMAGIC_STRING ") loading\n", IVTV_VERSION); + printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION); memset(ivtv_cards, 0, sizeof(ivtv_cards)); /* Validate parameters */ if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) { - printk(KERN_ERR "ivtv: ivtv_first_minor must be between 0 and %d. Exiting...\n", + printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n", IVTV_MAX_CARDS - 1); return -1; } - if (ivtv_debug < 0 || ivtv_debug > 511) { + if (ivtv_debug < 0 || ivtv_debug > 1023) { ivtv_debug = 0; - printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 511!\n"); + printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 1023\n"); } if (pci_register_driver(&ivtv_pci_driver)) { printk(KERN_ERR "ivtv: Error detecting PCI card\n"); return -ENODEV; } - printk(KERN_INFO "ivtv: ==================== END INIT IVTV ====================\n"); + printk(KERN_INFO "ivtv: End initialization\n"); return 0; } diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index e6e56f175f3..91b588d261a 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -268,6 +268,8 @@ extern const u32 yuv_offset[4]; #define IVTV_DBGFLG_IRQ (1 << 6) #define IVTV_DBGFLG_DEC (1 << 7) #define IVTV_DBGFLG_YUV (1 << 8) +/* Flag to turn on high volume debugging */ +#define IVTV_DBGFLG_HIGHVOL (1 << 9) /* NOTE: extra space before comma in 'itv->num , ## args' is required for gcc-2.95, otherwise it won't compile. */ @@ -286,6 +288,21 @@ extern const u32 yuv_offset[4]; #define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) #define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) +#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ + do { \ + if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ + printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \ + } while (0) +#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warning", fmt , ## args) +#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info",fmt , ## args) +#define IVTV_DEBUG_HI_API(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_API, "api", fmt , ## args) +#define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args) +#define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) +#define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) +#define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) +#define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args) +#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) + #define IVTV_FB_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & ivtv_debug) \ @@ -650,7 +667,6 @@ struct vbi_info { /* convenience pointer to sliced struct in vbi_in union */ struct v4l2_sliced_vbi_format *sliced_in; u32 service_set_in; - u32 service_set_out; int insert_mpeg; /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. @@ -723,6 +739,7 @@ struct ivtv { int search_pack_header; spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ + struct mutex serialize_lock; /* lock used to serialize starting streams */ /* User based DMA for OSD */ struct ivtv_user_dma udma; @@ -831,7 +848,7 @@ int ivtv_set_output_mode(struct ivtv *itv, int mode); struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv); /* Return non-zero if a signal is pending */ -int ivtv_sleep_timeout(int timeout, int intr); +int ivtv_msleep_timeout(unsigned int msecs, int intr); /* Wait on queue, returns -EINTR if interrupted */ int ivtv_waitq(wait_queue_head_t *waitq); diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 555d5e6369c..8e97a938398 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -218,7 +218,7 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, /* Process pending program info updates and pending VBI data */ ivtv_update_pgm_info(itv); - if (jiffies - itv->dualwatch_jiffies > HZ) { + if (jiffies - itv->dualwatch_jiffies > msecs_to_jiffies(1000)) { itv->dualwatch_jiffies = jiffies; ivtv_dualwatch(itv); } @@ -406,7 +406,7 @@ static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t co ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; struct ivtv *itv = s->itv; - IVTV_DEBUG_INFO("read %zd from %s, got %zd\n", count, s->name, rc); + IVTV_DEBUG_HI_INFO("read %zd from %s, got %zd\n", count, s->name, rc); if (rc > 0) pos += rc; return rc; @@ -497,7 +497,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ struct ivtv_stream *s = &itv->streams[id->type]; int rc; - IVTV_DEBUG_IOCTL("read %zd bytes from %s\n", count, s->name); + IVTV_DEBUG_HI_IOCTL("read %zd bytes from %s\n", count, s->name); rc = ivtv_start_capture(id); if (rc) @@ -535,7 +535,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c int rc; DEFINE_WAIT(wait); - IVTV_DEBUG_IOCTL("write %zd bytes to %s\n", count, s->name); + IVTV_DEBUG_HI_IOCTL("write %zd bytes to %s\n", count, s->name); if (s->type != IVTV_DEC_STREAM_TYPE_MPG && s->type != IVTV_DEC_STREAM_TYPE_YUV && @@ -643,7 +643,7 @@ retry: to transfer the rest. */ if (count && !(filp->f_flags & O_NONBLOCK)) goto retry; - IVTV_DEBUG_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); + IVTV_DEBUG_HI_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); return bytes_written; } @@ -832,7 +832,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) if (itv == NULL) { /* Couldn't find a device registered on that minor, shouldn't happen! */ - printk(KERN_WARNING "ivtv: no ivtv device found on minor %d\n", minor); + printk(KERN_WARNING "ivtv: No ivtv device found on minor %d\n", minor); return -ENXIO; } @@ -924,7 +924,7 @@ void ivtv_unmute(struct ivtv *itv) if (atomic_read(&itv->capturing) == 0) ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); - ivtv_sleep_timeout(HZ / 10, 0); + ivtv_msleep_timeout(100, 0); if (atomic_read(&itv->capturing)) { ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index d4c910b782a..d0feabf9308 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c @@ -36,7 +36,7 @@ #define IVTV_CMD_SPU_STOP 0x00000001 #define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A #define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640 -#define IVTV_SDRAM_SLEEPTIME (60 * HZ / 100) /* 600 ms */ +#define IVTV_SDRAM_SLEEPTIME 600 #define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg" #define IVTV_DECODE_INIT_MPEG_SIZE (152*1024) @@ -56,14 +56,12 @@ retry: volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; const u32 *src = (const u32 *)fw->data; - /* temporarily allow 256 KB encoding firmwares as well for - compatibility with blackbird cards */ - if (fw->size != size && fw->size != 256 * 1024) { + if (fw->size != size) { /* Due to race conditions in firmware loading (esp. with udev <0.95) the wrong file was sometimes loaded. So we check filesizes to see if at least the right-sized file was loaded. If not, then we retry. */ - IVTV_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size); + IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size); release_firmware(fw); retries--; goto retry; @@ -75,11 +73,11 @@ retry: src++; } release_firmware(fw); - IVTV_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); + IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); return size; } - IVTV_ERR("unable to open firmware %s (must be %ld bytes)\n", fn, size); - IVTV_ERR("did you put the firmware in the hotplug firmware directory?\n"); + IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); + IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } @@ -91,7 +89,7 @@ void ivtv_halt_firmware(struct ivtv *itv) if (itv->enc_mbox.mbox) ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0); - ivtv_sleep_timeout(HZ / 100, 0); + ivtv_msleep_timeout(10, 0); itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL; IVTV_DEBUG_INFO("Stopping VDM\n"); @@ -115,7 +113,7 @@ void ivtv_halt_firmware(struct ivtv *itv) IVTV_DEBUG_INFO("Stopping SPU\n"); write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU); - ivtv_sleep_timeout(HZ / 100, 0); + ivtv_msleep_timeout(10, 0); IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n"); write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE); @@ -131,9 +129,8 @@ void ivtv_halt_firmware(struct ivtv *itv) write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH); } - IVTV_DEBUG_INFO("Sleeping for %dms (600 recommended)\n", - (int)(IVTV_SDRAM_SLEEPTIME * 1000 / HZ)); - ivtv_sleep_timeout(IVTV_SDRAM_SLEEPTIME, 0); + IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME); + ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0); } void ivtv_firmware_versions(struct ivtv *itv) @@ -206,12 +203,12 @@ int ivtv_firmware_init(struct ivtv *itv) /* start firmware */ write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU); - ivtv_sleep_timeout(HZ / 10, 0); + ivtv_msleep_timeout(100, 0); if (itv->has_cx23415) write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU); else write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU); - ivtv_sleep_timeout(HZ / 10, 0); + ivtv_msleep_timeout(100, 0); /* find mailboxes and ping firmware */ itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE); @@ -266,7 +263,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv) IVTV_DECODE_INIT_MPEG_FILENAME); } else { ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0); - ivtv_sleep_timeout(HZ / 10, 0); + ivtv_msleep_timeout(100, 0); } ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); } diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index bc8f8ca2961..6a5a7aa6697 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c @@ -115,8 +115,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv) curout = (curout & ~0xF) | 1; write_reg(curout, IVTV_REG_GPIO_OUT); /* We could use something else for smaller time */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(msecs_to_jiffies(1)); curout |= 2; write_reg(curout, IVTV_REG_GPIO_OUT); curdir &= ~0x80; @@ -131,20 +130,18 @@ int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr) if (itv->card->type != IVTV_CARD_PG600V2 || itv->options.tuner != TUNER_XCEIVE_XC3028) return -EINVAL; - IVTV_INFO("Resetting tuner.\n"); + IVTV_INFO("Resetting tuner\n"); curout = read_reg(IVTV_REG_GPIO_OUT); curdir = read_reg(IVTV_REG_GPIO_DIR); curdir |= (1 << 12); /* GPIO bit 12 */ curout &= ~(1 << 12); write_reg(curout, IVTV_REG_GPIO_OUT); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(msecs_to_jiffies(1)); curout |= (1 << 12); write_reg(curout, IVTV_REG_GPIO_OUT); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 50624c6a62a..b3557435456 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -144,7 +144,7 @@ static int attach_inform(struct i2c_client *client) } } if (i == I2C_CLIENTS_MAX) { - IVTV_ERR("insufficient room for new I2C client!\n"); + IVTV_ERR("Insufficient room for new I2C client\n"); } return 0; } @@ -236,7 +236,7 @@ static int ivtv_ack(struct ivtv *itv) int ret = 0; if (ivtv_getscl(itv) == 1) { - IVTV_DEBUG_I2C("SCL was high starting an ack\n"); + IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n"); ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n"); @@ -263,7 +263,7 @@ static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte) { int i, bit; - IVTV_DEBUG_I2C("write %x\n",byte); + IVTV_DEBUG_HI_I2C("write %x\n",byte); for (i = 0; i < 8; ++i, byte<<=1) { ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { @@ -318,7 +318,7 @@ static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack) ivtv_scldelay(itv); ivtv_setscl(itv, 0); ivtv_scldelay(itv); - IVTV_DEBUG_I2C("read %x\n",*byte); + IVTV_DEBUG_HI_I2C("read %x\n",*byte); return 0; } @@ -330,7 +330,7 @@ static int ivtv_start(struct ivtv *itv) sda = ivtv_getsda(itv); if (sda != 1) { - IVTV_DEBUG_I2C("SDA was low at start\n"); + IVTV_DEBUG_HI_I2C("SDA was low at start\n"); ivtv_setsda(itv, 1); if (!ivtv_waitsda(itv, 1)) { IVTV_DEBUG_I2C("SDA stuck low\n"); @@ -355,7 +355,7 @@ static int ivtv_stop(struct ivtv *itv) int i; if (ivtv_getscl(itv) != 0) { - IVTV_DEBUG_I2C("SCL not low when stopping\n"); + IVTV_DEBUG_HI_I2C("SCL not low when stopping\n"); ivtv_setscl(itv, 0); if (!ivtv_waitscl(itv, 0)) { IVTV_DEBUG_I2C("SCL could not be set low\n"); @@ -569,7 +569,7 @@ int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg } } if (cmd != VIDIOC_G_CHIP_IDENT) - IVTV_ERR("i2c addr 0x%02x not found for command 0x%x!\n", addr, cmd); + IVTV_ERR("i2c addr 0x%02x not found for command 0x%x\n", addr, cmd); return -ENODEV; } @@ -640,7 +640,7 @@ int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg) addr = ivtv_i2c_hw_addr(itv, hw); if (addr < 0) { - IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x!\n", + IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x\n", hw, ivtv_i2c_hw_name(hw), cmd); return addr; } @@ -655,7 +655,7 @@ int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg) addr = ivtv_i2c_id_addr(itv, id); if (addr < 0) { if (cmd != VIDIOC_G_CHIP_IDENT) - IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x!\n", + IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x\n", id, ivtv_i2c_id_name(id), cmd); return addr; } @@ -696,7 +696,7 @@ int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg) void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg) { if (itv->i2c_adap.algo == NULL) { - IVTV_ERR("adapter is not set"); + IVTV_ERR("Adapter is not set"); return; } i2c_clients_command(&itv->i2c_adap, cmd, arg); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 57af1762de1..4773453e8da 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1159,7 +1159,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void memset(fb, 0, sizeof(*fb)); if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - break; + return -EINVAL; fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; fb->fmt.pixelformat = itv->osd_pixelformat; @@ -1179,7 +1179,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void struct v4l2_framebuffer *fb = arg; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - break; + return -EINVAL; itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index ba98bf054f2..fcd6e7f5f12 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c @@ -48,7 +48,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) struct list_head *p; int i = 0; - IVTV_DEBUG_DMA("ivtv_pio_work_handler\n"); + IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || s->v4l2dev == NULL || !ivtv_use_pio(s)) { itv->cur_pio_stream = -1; @@ -56,7 +56,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); return; } - IVTV_DEBUG_DMA("Process PIO %s\n", s->name); + IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name); buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); list_for_each(p, &s->q_dma.list) { struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); @@ -187,7 +187,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA bytes_needed += UVsize; } - IVTV_DEBUG_DMA("%s %s: 0x%08x bytes at 0x%08x\n", + IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset); rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed); @@ -242,7 +242,7 @@ static void dma_post(struct ivtv_stream *s) u32 *u32buf; int x = 0; - IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", + IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, s->dma_offset); list_for_each(p, &s->q_dma.list) { buf = list_entry(p, struct ivtv_buffer, list); @@ -321,7 +321,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) unsigned long flags = 0; int idx = 0; - IVTV_DEBUG_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); + IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); list_for_each(p, &s->q_predma.list) { struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); @@ -368,7 +368,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; int i; - IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); + IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); @@ -397,12 +397,17 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) itv->vbi.dma_offset = s_vbi->dma_offset; s_vbi->SG_length = 0; set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); - IVTV_DEBUG_DMA("include DMA for %s\n", s->name); + IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name); } /* Mark last buffer size for Interrupt flag */ s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); + if (s->type == IVTV_ENC_STREAM_TYPE_VBI) + set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); + else + clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); + if (ivtv_use_pio(s)) { for (i = 0; i < s->SG_length; i++) { s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); @@ -420,7 +425,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); set_bit(IVTV_F_I_DMA, &itv->i_flags); itv->cur_dma_stream = s->type; - itv->dma_timer.expires = jiffies + HZ / 10; + itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); add_timer(&itv->dma_timer); } } @@ -431,13 +436,13 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); - IVTV_DEBUG_DMA("start DMA for %s\n", s->name); + IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); /* put SG Handle into register 0x0c */ write_reg(s->SG_handle, IVTV_REG_DECDMAADDR); write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); set_bit(IVTV_F_I_DMA, &itv->i_flags); itv->cur_dma_stream = s->type; - itv->dma_timer.expires = jiffies + HZ / 10; + itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); add_timer(&itv->dma_timer); } @@ -447,7 +452,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) struct ivtv_buffer *buf; int hw_stream_type; - IVTV_DEBUG_IRQ("DEC DMA READ\n"); + IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); del_timer(&itv->dma_timer); if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS)); @@ -462,7 +467,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; hw_stream_type = 0; } - IVTV_DEBUG_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); + IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); ivtv_stream_sync_for_cpu(s); @@ -495,7 +500,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) del_timer(&itv->dma_timer); ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); - IVTV_DEBUG_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); + IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags)) data[1] = 3; else if (data[1] > 2) @@ -532,7 +537,7 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) return; } s = &itv->streams[itv->cur_pio_stream]; - IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name); + IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); s->SG_length = 0; clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); clear_bit(IVTV_F_I_PIO, &itv->i_flags); @@ -590,14 +595,13 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) /* Get DMA destination and size arguments from card */ ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); - IVTV_DEBUG_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); + IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); if (data[0] > 2 || data[1] == 0 || data[2] == 0) { IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n", data[0], data[1], data[2]); return; } - clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); s = &itv->streams[ivtv_stream_map[data[0]]]; if (!stream_enc_dma_append(s, data)) { set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); @@ -610,7 +614,7 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s; - IVTV_DEBUG_IRQ("ENC START VBI CAP\n"); + IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; /* If more than two VBI buffers are pending, then @@ -634,7 +638,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) then start a DMA request for just the VBI data. */ if (!stream_enc_dma_append(s, data) && !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { - set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); } } @@ -644,7 +647,7 @@ static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; - IVTV_DEBUG_IRQ("DEC VBI REINSERT\n"); + IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n"); if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && !stream_enc_dma_append(s, data)) { set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); @@ -669,7 +672,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv) itv->dma_data_req_offset = data[1]; s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; } - IVTV_DEBUG_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, + IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, itv->dma_data_req_offset, itv->dma_data_req_size); if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) { set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); @@ -791,10 +794,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) /* Exclude interrupts noted below from the output, otherwise the log is flooded with these messages */ if (combo & ~0xff6d0400) - IVTV_DEBUG_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); + IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) { - IVTV_DEBUG_IRQ("DEC DMA COMPLETE\n"); + IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n"); } if (combo & IVTV_IRQ_DMA_READ) { diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 6ae42a3b03c..814a673712b 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c @@ -37,6 +37,7 @@ #define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */ #define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */ #define API_DMA (1 << 3) /* DMA mailbox, has special handling */ +#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ @@ -77,11 +78,11 @@ static const struct ivtv_api_info api_info[256] = { API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE), API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT), API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA), + API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL), API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT), API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE), API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT), - API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB), + API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL), API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE), API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT), API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE), @@ -102,7 +103,7 @@ static const struct ivtv_api_info api_info[256] = { API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE), API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT), API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA), + API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL), API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT), API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT), API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE), @@ -175,9 +176,9 @@ static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int f /* Sleep before a retry, if not atomic */ if (!(flags & API_NO_WAIT_MB)) { - if (jiffies - then > retries * HZ / 100) + if (jiffies - then > msecs_to_jiffies(10*retries)) break; - ivtv_sleep_timeout(HZ / 100, 0); + ivtv_msleep_timeout(10, 0); } } return -ENODEV; @@ -212,7 +213,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) { struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox; volatile struct ivtv_mailbox __iomem *mbox; - int api_timeout = HZ; + int api_timeout = msecs_to_jiffies(1000); int flags, mb, i; unsigned long then; @@ -227,7 +228,12 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) return -EINVAL; } - IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name); + if (api_info[cmd].flags & API_HIGH_VOL) { + IVTV_DEBUG_HI_API("API Call: %s\n", api_info[cmd].name); + } + else { + IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name); + } /* clear possibly uninitialized part of data array */ for (i = args; i < CX2341X_MBOX_MAX_DATA; i++) @@ -237,7 +243,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) data, then just return 0 as there is no need to issue this command again. Just an optimization to prevent unnecessary use of mailboxes. */ if (itv->api_cache[cmd].last_jiffies && - jiffies - itv->api_cache[cmd].last_jiffies < HZ * 1800 && + jiffies - itv->api_cache[cmd].last_jiffies < msecs_to_jiffies(1800000) && !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { itv->api_cache[cmd].last_jiffies = jiffies; return 0; @@ -262,7 +268,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) } if ((flags & API_FAST_RESULT) == API_FAST_RESULT) - api_timeout = HZ / 10; + api_timeout = msecs_to_jiffies(100); mb = get_mailbox(itv, mbdata, flags); if (mb < 0) { @@ -295,11 +301,12 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) if (flags & API_NO_WAIT_RES) mdelay(1); else - ivtv_sleep_timeout(HZ / 100, 0); + ivtv_msleep_timeout(10, 0); } - if (jiffies - then > HZ / 10) - IVTV_DEBUG_WARN("%s took %lu jiffies (%d per HZ)\n", - api_info[cmd].name, jiffies - then, HZ); + if (jiffies - then > msecs_to_jiffies(100)) + IVTV_DEBUG_WARN("%s took %u jiffies\n", + api_info[cmd].name, + jiffies_to_msecs(jiffies - then)); for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) data[i] = readl(&mbox->data[i]); diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 6af88ae9295..322b347b67c 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -446,6 +446,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) if (s->v4l2dev == NULL) return -EINVAL; + /* Big serialization lock to ensure no two streams are started + simultaneously: that can give all sorts of weird results. */ + mutex_lock(&itv->serialize_lock); IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); switch (s->type) { @@ -487,6 +490,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) 0, sizeof(itv->vbi.sliced_mpeg_size)); break; default: + mutex_unlock(&itv->serialize_lock); return -EINVAL; } s->subtype = subtype; @@ -561,13 +565,14 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) /* Initialize Digitizer for Capture */ ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); - ivtv_sleep_timeout(HZ / 10, 0); + ivtv_msleep_timeout(100, 0); } /* begin_capture */ if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) { IVTV_DEBUG_WARN( "Error starting capture!\n"); + mutex_unlock(&itv->serialize_lock); return -EINVAL; } @@ -583,6 +588,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) /* you're live! sit back and await interrupts :) */ atomic_inc(&itv->capturing); + mutex_unlock(&itv->serialize_lock); return 0; } @@ -762,17 +768,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); - /* only run these if we're shutting down the last cap */ - if (atomic_read(&itv->capturing) - 1 == 0) { - /* event notification (off) */ - if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { - /* type: 0 = refresh */ - /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ - ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); - ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); - } - } - then = jiffies; if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { @@ -786,8 +781,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) set_current_state(TASK_INTERRUPTIBLE); /* wait 2s for EOS interrupt */ - while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && jiffies < then + 2 * HZ) { - schedule_timeout(HZ / 100); + while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && + jiffies < then + msecs_to_jiffies (2000)) { + schedule_timeout(msecs_to_jiffies(10)); } /* To convert jiffies to ms, we must multiply by 1000 @@ -812,7 +808,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) then = jiffies; /* Make sure DMA is complete */ add_wait_queue(&s->waitq, &wait); - set_current_state(TASK_INTERRUPTIBLE); do { /* check if DMA is pending */ if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */ @@ -827,9 +822,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) { break; } - - ivtv_sleep_timeout(HZ / 100, 1); - } while (then + HZ * 2 > jiffies); + } while (!ivtv_msleep_timeout(10, 1) && + then + msecs_to_jiffies(2000) > jiffies); set_current_state(TASK_RUNNING); remove_wait_queue(&s->waitq, &wait); @@ -840,17 +834,30 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) /* Clear capture and no-read bits */ clear_bit(IVTV_F_S_STREAMING, &s->s_flags); + /* ensure these global cleanup actions are done only once */ + mutex_lock(&itv->serialize_lock); + if (s->type == IVTV_ENC_STREAM_TYPE_VBI) ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); if (atomic_read(&itv->capturing) > 0) { + mutex_unlock(&itv->serialize_lock); return 0; } /* Set the following Interrupt mask bits for capture */ ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); + /* event notification (off) */ + if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { + /* type: 0 = refresh */ + /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ + ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); + ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); + } + wake_up(&s->waitq); + mutex_unlock(&itv->serialize_lock); return 0; } @@ -887,7 +894,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) break; tmp = data[3]; } - if (ivtv_sleep_timeout(HZ/10, 1)) + if (ivtv_msleep_timeout(100, 1)) break; } } diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 3ba46e07ea1..a7282a91bd9 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c @@ -219,31 +219,23 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count) int found_cc = 0; int cc_pos = itv->vbi.cc_pos; - if (itv->vbi.service_set_out == 0) - return -EPERM; - while (count >= sizeof(struct v4l2_sliced_vbi_data)) { switch (p->id) { case V4L2_SLICED_CAPTION_525: - if (p->id == V4L2_SLICED_CAPTION_525 && - p->line == 21 && - (itv->vbi.service_set_out & - V4L2_SLICED_CAPTION_525) == 0) { - break; - } - found_cc = 1; - if (p->field) { - cc[2] = p->data[0]; - cc[3] = p->data[1]; - } else { - cc[0] = p->data[0]; - cc[1] = p->data[1]; + if (p->line == 21) { + found_cc = 1; + if (p->field) { + cc[2] = p->data[0]; + cc[3] = p->data[1]; + } else { + cc[0] = p->data[0]; + cc[1] = p->data[1]; + } } break; case V4L2_SLICED_VPS: - if (p->line == 16 && p->field == 0 && - (itv->vbi.service_set_out & V4L2_SLICED_VPS)) { + if (p->line == 16 && p->field == 0) { itv->vbi.vps[0] = p->data[2]; itv->vbi.vps[1] = p->data[8]; itv->vbi.vps[2] = p->data[9]; @@ -255,8 +247,7 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count) break; case V4L2_SLICED_WSS_625: - if (p->line == 23 && p->field == 0 && - (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) { + if (p->line == 23 && p->field == 0) { /* No lock needed for WSS */ itv->vbi.wss = p->data[0] | (p->data[1] << 8); itv->vbi.wss_found = 1; |