diff options
Diffstat (limited to 'linux/drivers/media/video/cx18')
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.c | 13 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.h | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-io.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-io.h | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-irq.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-mailbox.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-streams.c | 36 |
7 files changed, 40 insertions, 28 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c index 085121c2b..c95230999 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.c +++ b/linux/drivers/media/video/cx18/cx18-driver.c @@ -613,6 +613,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { int retval = 0; + int i; int vbi_buf_size; u32 devtype; struct cx18 *cx; @@ -698,7 +699,8 @@ static int __devinit cx18_probe(struct pci_dev *dev, /* active i2c */ CX18_DEBUG_INFO("activating i2c...\n"); - if (init_cx18_i2c(cx)) { + retval = init_cx18_i2c(cx); + if (retval) { CX18_ERR("Could not initialize i2c\n"); goto free_map; } @@ -730,8 +732,6 @@ static int __devinit cx18_probe(struct pci_dev *dev, cx->std = V4L2_STD_NTSC_M; if (cx->options.tuner == -1) { - int i; - for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) { if ((cx->std & cx->card->tuners[i].std) == 0) continue; @@ -836,8 +836,11 @@ err: CX18_ERR("Error %d on initialization\n", retval); cx18_log_statistics(cx); - kfree(cx18_cards[cx18_cards_active]); - cx18_cards[cx18_cards_active] = NULL; + i = cx->num; + spin_lock(&cx18_cards_lock); + kfree(cx18_cards[i]); + cx18_cards[i] = NULL; + spin_unlock(&cx18_cards_lock); return retval; } diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index fa8be0731..a4b1708fa 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -41,6 +41,7 @@ #include <linux/pagemap.h> #include <linux/workqueue.h> #include <linux/mutex.h> +#include <asm/byteorder.h> #include <linux/dvb/video.h> #include <linux/dvb/audio.h> diff --git a/linux/drivers/media/video/cx18/cx18-io.c b/linux/drivers/media/video/cx18/cx18-io.c index 700ab9439..31be5e868 100644 --- a/linux/drivers/media/video/cx18/cx18-io.c +++ b/linux/drivers/media/video/cx18/cx18-io.c @@ -218,7 +218,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg(cx, val, SW1_INT_STATUS); + cx18_write_reg_noretry(cx, val, SW1_INT_STATUS); r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); } @@ -233,7 +233,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) { u32 r; - cx18_write_reg(cx, val, SW2_INT_STATUS); + cx18_write_reg_noretry(cx, val, SW2_INT_STATUS); r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); } diff --git a/linux/drivers/media/video/cx18/cx18-io.h b/linux/drivers/media/video/cx18/cx18-io.h index 197d4fbd9..287a5e8bf 100644 --- a/linux/drivers/media/video/cx18/cx18-io.h +++ b/linux/drivers/media/video/cx18/cx18-io.h @@ -39,7 +39,7 @@ static inline void cx18_io_delay(struct cx18 *cx) /* Statistics gathering */ static inline -void cx18_log_write_retries(struct cx18 *cx, int i, const void *addr) +void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr) { if (i > CX18_MAX_MMIO_RETRIES) i = CX18_MAX_MMIO_RETRIES; @@ -48,7 +48,7 @@ void cx18_log_write_retries(struct cx18 *cx, int i, const void *addr) } static inline -void cx18_log_read_retries(struct cx18 *cx, int i, const void *addr) +void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr) { if (i > CX18_MAX_MMIO_RETRIES) i = CX18_MAX_MMIO_RETRIES; diff --git a/linux/drivers/media/video/cx18/cx18-irq.c b/linux/drivers/media/video/cx18/cx18-irq.c index 85a56974b..038f70323 100644 --- a/linux/drivers/media/video/cx18/cx18-irq.c +++ b/linux/drivers/media/video/cx18/cx18-irq.c @@ -153,9 +153,9 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; - cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS); - cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); - cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); + cx18_write_reg_noretry(cx, sw2&sw2_mask, SW2_INT_STATUS); + cx18_write_reg_noretry(cx, sw1&sw1_mask, SW1_INT_STATUS); + cx18_write_reg_noretry(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); if (sw1 || sw2 || hw2) CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); diff --git a/linux/drivers/media/video/cx18/cx18-mailbox.c b/linux/drivers/media/video/cx18/cx18-mailbox.c index 9d18dd22d..87f7c8e2c 100644 --- a/linux/drivers/media/video/cx18/cx18-mailbox.c +++ b/linux/drivers/media/video/cx18/cx18-mailbox.c @@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) cx18_setup_page(cx, SCB_OFFSET); cx18_write_sync(cx, mb->request, &ack_mb->ack); - cx18_write_reg(cx, ack_irq, SW2_INT_SET); + cx18_write_reg_noretry(cx, ack_irq, SW2_INT_SET); return 0; } @@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) } if (info->flags & API_FAST) timeout /= 2; - cx18_write_reg(cx, irq, SW1_INT_SET); + cx18_write_reg_noretry(cx, irq, SW1_INT_SET); while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) && cnt < 660) { diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c index f85f4a2cd..8ead4025e 100644 --- a/linux/drivers/media/video/cx18/cx18-streams.c +++ b/linux/drivers/media/video/cx18/cx18-streams.c @@ -200,16 +200,18 @@ static int cx18_prep_dev(struct cx18 *cx, int type) /* Initialize v4l2 variables and register v4l2 devices */ int cx18_streams_setup(struct cx18 *cx) { - int type; + int type, ret; /* Setup V4L2 Devices */ for (type = 0; type < CX18_MAX_STREAMS; type++) { /* Prepare device */ - if (cx18_prep_dev(cx, type)) + ret = cx18_prep_dev(cx, type); + if (ret < 0) break; /* Allocate Stream */ - if (cx18_stream_alloc(&cx->streams[type])) + ret = cx18_stream_alloc(&cx->streams[type]); + if (ret < 0) break; } if (type == CX18_MAX_STREAMS) @@ -217,14 +219,14 @@ int cx18_streams_setup(struct cx18 *cx) /* One or more streams could not be initialized. Clean 'em all up. */ cx18_streams_cleanup(cx, 0); - return -ENOMEM; + return ret; } static int cx18_reg_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; int vfl_type = cx18_stream_info[type].vfl_type; - int num; + int num, ret; /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? * We need a VFL_TYPE_TS defined. @@ -233,9 +235,10 @@ static int cx18_reg_dev(struct cx18 *cx, int type) /* just return if no DVB is supported */ if ((cx->card->hw_all & CX18_HW_DVB) == 0) return 0; - if (cx18_dvb_register(s) < 0) { + ret = cx18_dvb_register(s); + if (ret < 0) { CX18_ERR("DVB failed to register\n"); - return -EINVAL; + return ret; } } @@ -252,12 +255,13 @@ static int cx18_reg_dev(struct cx18 *cx, int type) } /* Register device. First try the desired minor, then any free one. */ - if (video_register_device(s->v4l2dev, vfl_type, num)) { + ret = video_register_device(s->v4l2dev, vfl_type, num); + if (ret < 0) { CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", s->name, num); video_device_release(s->v4l2dev); s->v4l2dev = NULL; - return -ENOMEM; + return ret; } num = s->v4l2dev->num; @@ -290,18 +294,22 @@ static int cx18_reg_dev(struct cx18 *cx, int type) int cx18_streams_register(struct cx18 *cx) { int type; - int err = 0; + int err; + int ret = 0; /* Register V4L2 devices */ - for (type = 0; type < CX18_MAX_STREAMS; type++) - err |= cx18_reg_dev(cx, type); + for (type = 0; type < CX18_MAX_STREAMS; type++) { + err = cx18_reg_dev(cx, type); + if (err && ret == 0) + ret = err; + } - if (err == 0) + if (ret == 0) return 0; /* One or more streams could not be initialized. Clean 'em all up. */ cx18_streams_cleanup(cx, 1); - return -ENOMEM; + return ret; } /* Unregister v4l2 devices */ |