diff options
Diffstat (limited to 'drivers/media')
28 files changed, 198 insertions, 115 deletions
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 0b4616b87195..c0363f1b6c90 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -206,8 +206,6 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) /* TODO */ dvbdev->users--; if (dvbdev->users == 1 && dmxdev->exit == 1) { - fops_put(file->f_op); - file->f_op = NULL; mutex_unlock(&dmxdev->mutex); wake_up(&dvbdev->wait_queue); } else @@ -1120,8 +1118,6 @@ static int dvb_demux_release(struct inode *inode, struct file *file) mutex_lock(&dmxdev->mutex); dmxdev->dvbdev->users--; if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) { - fops_put(file->f_op); - file->f_op = NULL; mutex_unlock(&dmxdev->mutex); wake_up(&dmxdev->dvbdev->wait_queue); } else diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 401ef64f92c6..983db75de350 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -74,22 +74,15 @@ static int dvb_device_open(struct inode *inode, struct file *file) if (dvbdev && dvbdev->fops) { int err = 0; - const struct file_operations *old_fops; + const struct file_operations *new_fops; - file->private_data = dvbdev; - old_fops = file->f_op; - file->f_op = fops_get(dvbdev->fops); - if (file->f_op == NULL) { - file->f_op = old_fops; + new_fops = fops_get(dvbdev->fops); + if (!new_fops) goto fail; - } - if(file->f_op->open) + file->private_data = dvbdev; + replace_fops(file, new_fops); + if (file->f_op->open) err = file->f_op->open(inode,file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); up_read(&minor_rwsem); mutex_unlock(&dvbdev_mutex); return err; diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index 2521f7e23018..e79749cfec81 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -912,14 +912,8 @@ static int tda10071_init(struct dvb_frontend *fe) { 0xd5, 0x03, 0x03 }, }; - /* firmware status */ - ret = tda10071_rd_reg(priv, 0x51, &tmp); - if (ret) - goto error; - - if (!tmp) { + if (priv->warm) { /* warm state - wake up device from sleep */ - priv->warm = 1; for (i = 0; i < ARRAY_SIZE(tab); i++) { ret = tda10071_wr_reg_mask(priv, tab[i].reg, @@ -937,7 +931,6 @@ static int tda10071_init(struct dvb_frontend *fe) goto error; } else { /* cold state - try to download firmware */ - priv->warm = 0; /* request the firmware, this will block and timeout */ ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent); diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index bb0c99d7a4f1..b06a7e54ee0d 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -628,16 +628,13 @@ static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable) static const struct v4l2_dv_timings_cap ad9389b_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 170000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 170000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static int ad9389b_s_dv_timings(struct v4l2_subdev *sd, diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 7a576097471f..7c8d971f1f61 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -119,16 +119,14 @@ static int adv7511_s_clock_freq(struct v4l2_subdev *sd, u32 freq); static const struct v4l2_dv_timings_cap adv7511_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = ADV7511_MAX_WIDTH, - .max_height = ADV7511_MAX_HEIGHT, - .min_pixelclock = ADV7511_MIN_PIXELCLOCK, - .max_pixelclock = ADV7511_MAX_PIXELCLOCK, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, ADV7511_MAX_WIDTH, 0, ADV7511_MAX_HEIGHT, + ADV7511_MIN_PIXELCLOCK, ADV7511_MAX_PIXELCLOCK, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static inline struct adv7511_state *get_adv7511_state(struct v4l2_subdev *sd) @@ -1126,6 +1124,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->i2c_edid = i2c_new_dummy(client->adapter, state->i2c_edid_addr >> 1); if (state->i2c_edid == NULL) { v4l2_err(sd, "failed to register edid i2c client\n"); + err = -ENOMEM; goto err_entity; } @@ -1133,6 +1132,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->work_queue = create_singlethread_workqueue(sd->name); if (state->work_queue == NULL) { v4l2_err(sd, "could not create workqueue\n"); + err = -ENOMEM; goto err_unreg_cec; } diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index d1748901337c..22f729d66a96 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -546,30 +546,24 @@ static inline bool is_digital_input(struct v4l2_subdev *sd) static const struct v4l2_dv_timings_cap adv7842_timings_cap_analog = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 170000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 170000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static const struct v4l2_dv_timings_cap adv7842_timings_cap_digital = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 225000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 225000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static inline const struct v4l2_dv_timings_cap * diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index a58a8f663ffb..d9f65d7e3e58 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -46,14 +46,10 @@ struct ths8200_state { static const struct v4l2_dv_timings_cap ths8200_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1080, - .min_pixelclock = 25000000, - .max_pixelclock = 148500000, - .standards = V4L2_DV_BT_STD_CEA861, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE, - }, + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1080, 25000000, 148500000, + V4L2_DV_BT_STD_CEA861, V4L2_DV_BT_CAP_PROGRESSIVE) }; static inline struct ths8200_state *to_state(struct v4l2_subdev *sd) diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index e12bbd8c3f0b..fb60da85bc2c 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1455,6 +1455,7 @@ static int video_release(struct file *file) /* stop video capture */ if (res_check(fh, RESOURCE_VIDEO)) { + pm_qos_remove_request(&dev->qos_request); videobuf_streamoff(&fh->cap); res_free(dev,fh,RESOURCE_VIDEO); } diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 8068d7b64155..eb70dda8cbf3 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -112,7 +112,7 @@ config VIDEO_OMAP3_DEBUG config VIDEO_S3C_CAMIF tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API - depends on (PLAT_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME + depends on (ARCH_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME select VIDEOBUF2_DMA_CONTIG ---help--- This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera @@ -203,7 +203,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" - depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS && HAS_DMA + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 4c1105977090..281916591437 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -422,7 +422,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) return ret; } - INIT_COMPLETION(bcap_dev->comp); + reinit_completion(&bcap_dev->comp); bcap_dev->stop = false; return 0; } diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 449d2fec9e87..4993610051ee 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -3232,13 +3232,12 @@ static int coda_probe(struct platform_device *pdev) dev->iram_size = CODA7_IRAM_SIZE; break; } - dev->iram_vaddr = gen_pool_alloc(dev->iram_pool, dev->iram_size); + dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool, + dev->iram_size, (dma_addr_t *)&dev->iram_paddr); if (!dev->iram_vaddr) { dev_err(&pdev->dev, "unable to alloc iram\n"); return -ENOMEM; } - dev->iram_paddr = gen_pool_virt_to_phys(dev->iram_pool, - dev->iram_vaddr); platform_set_drvdata(pdev, dev); diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index 53ad0f080179..d2d3b4b61435 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig @@ -29,7 +29,7 @@ config VIDEO_S5P_FIMC config VIDEO_S5P_MIPI_CSIS tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver" depends on REGULATOR - select S5P_SETUP_MIPIPHY + select GENERIC_PHY help This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2 receiver (MIPI-CSIS) devices. diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 0914230b42de..9fc2af6a0446 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -20,6 +20,7 @@ #include <linux/memory.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/phy/phy.h> #include <linux/platform_data/mipi-csis.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -180,6 +181,7 @@ struct csis_drvdata { * @sd: v4l2_subdev associated with CSIS device instance * @index: the hardware instance index * @pdev: CSIS platform device + * @phy: pointer to the CSIS generic PHY * @regs: mmaped I/O registers memory * @supplies: CSIS regulator supplies * @clock: CSIS clocks @@ -203,6 +205,7 @@ struct csis_state { struct v4l2_subdev sd; u8 index; struct platform_device *pdev; + struct phy *phy; void __iomem *regs; struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; struct clk *clock[NUM_CSIS_CLOCKS]; @@ -779,8 +782,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, "samsung,csis-wclk"); state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes; - of_node_put(node); + return 0; } #else @@ -829,6 +832,10 @@ static int s5pcsis_probe(struct platform_device *pdev) return -EINVAL; } + state->phy = devm_phy_get(dev, "csis"); + if (IS_ERR(state->phy)) + return PTR_ERR(state->phy); + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); state->regs = devm_ioremap_resource(dev, mem_res); if (IS_ERR(state->regs)) @@ -922,7 +929,7 @@ static int s5pcsis_pm_suspend(struct device *dev, bool runtime) mutex_lock(&state->lock); if (state->flags & ST_POWERED) { s5pcsis_stop_stream(state); - ret = s5p_csis_phy_enable(state->index, false); + ret = phy_power_off(state->phy); if (ret) goto unlock; ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES, @@ -958,7 +965,7 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime) state->supplies); if (ret) goto unlock; - ret = s5p_csis_phy_enable(state->index, true); + ret = phy_power_on(state->phy); if (!ret) { state->flags |= ST_POWERED; } else { diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 221ec428a01e..6a232239ee8c 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -21,6 +21,8 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/slab.h> #include <media/v4l2-common.h> @@ -1485,6 +1487,7 @@ static int viu_of_probe(struct platform_device *op) struct viu_reg __iomem *viu_regs; struct i2c_adapter *ad; int ret, viu_irq; + struct clk *clk; ret = of_address_to_resource(op->dev.of_node, 0, &r); if (ret) { @@ -1577,14 +1580,18 @@ static int viu_of_probe(struct platform_device *op) } /* enable VIU clock */ - viu_dev->clk = clk_get(&op->dev, "viu_clk"); - if (IS_ERR(viu_dev->clk)) { - dev_err(&op->dev, "failed to find the clock module!\n"); - ret = -ENODEV; + clk = devm_clk_get(&op->dev, "viu_clk"); + if (IS_ERR(clk)) { + dev_err(&op->dev, "failed to lookup the clock!\n"); + ret = PTR_ERR(clk); + goto err_clk; + } + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(&op->dev, "failed to enable the clock!\n"); goto err_clk; - } else { - clk_enable(viu_dev->clk); } + viu_dev->clk = clk; /* reset VIU module */ viu_reset(viu_dev->vr); @@ -1602,8 +1609,7 @@ static int viu_of_probe(struct platform_device *op) return ret; err_irq: - clk_disable(viu_dev->clk); - clk_put(viu_dev->clk); + clk_disable_unprepare(viu_dev->clk); err_clk: video_unregister_device(viu_dev->vdev); err_vdev: @@ -1626,8 +1632,7 @@ static int viu_of_remove(struct platform_device *op) free_irq(dev->irq, (void *)dev); irq_dispose_mapping(dev->irq); - clk_disable(dev->clk); - clk_put(dev->clk); + clk_disable_unprepare(dev->clk); video_unregister_device(dev->vdev); i2c_put_adapter(client->adapter); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index df3a0ec7fd2c..1c3608039663 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2182,9 +2182,9 @@ static int isp_probe(struct platform_device *pdev) isp->pdata = pdata; isp->ref_count = 0; - isp->raw_dmamask = DMA_BIT_MASK(32); - isp->dev->dma_mask = &isp->raw_dmamask; - isp->dev->coherent_dma_mask = DMA_BIT_MASK(32); + ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; platform_set_drvdata(pdev, isp); diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index cd3eff45ae7d..ce65d3ae1aa7 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -152,7 +152,6 @@ struct isp_xclk { * @mmio_base_phys: Array with physical L4 bus addresses for ISP register * regions. * @mmio_size: Array with ISP register regions size in bytes. - * @raw_dmamask: Raw DMA mask * @stat_lock: Spinlock for handling statistics * @isp_mutex: Mutex for serializing requests to ISP. * @crashed: Bitmask of crashed entities (indexed by entity ID) @@ -190,8 +189,6 @@ struct isp_device { unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST]; resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST]; - u64 raw_dmamask; - /* ISP Obj */ spinlock_t stat_lock; /* common lock for statistic drivers */ struct mutex isp_mutex; /* For handling ref_count field */ diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 15d23968d1de..9b88a4601007 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1423,6 +1423,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) jpeg->vfd_decoder->release = video_device_release; jpeg->vfd_decoder->lock = &jpeg->lock; jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev; + jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M; ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1); if (ret) { diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 7a9c5e9329f2..4f30341dc2ab 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -776,7 +776,7 @@ static int sh_vou_try_fmt_vid_out(struct file *file, void *priv, v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 1, &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); - for (i = 0; ARRAY_SIZE(vou_fmt); i++) + for (i = 0; i < ARRAY_SIZE(vou_fmt); i++) if (vou_fmt[i].pfmt == pix->pixelformat) return 0; diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 8f9f6211c52e..f975b7008692 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c @@ -266,7 +266,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; struct idmac_video_param *video = &ichan->params.video; const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt; - unsigned long flags; dma_cookie_t cookie; size_t new_size; @@ -328,7 +327,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0)); #endif - spin_lock_irqsave(&mx3_cam->lock, flags); + spin_lock_irq(&mx3_cam->lock); list_add_tail(&buf->queue, &mx3_cam->capture); if (!mx3_cam->active) @@ -351,7 +350,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) if (mx3_cam->active == buf) mx3_cam->active = NULL; - spin_unlock_irqrestore(&mx3_cam->lock, flags); + spin_unlock_irq(&mx3_cam->lock); error: vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 39882ddd2594..6ecdc39bb366 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -214,7 +214,7 @@ config RADIO_TIMBERDALE config RADIO_WL1273 tristate "Texas Instruments WL1273 I2C FM Radio" - depends on I2C && VIDEO_V4L2 && GENERIC_HARDIRQS + depends on I2C && VIDEO_V4L2 select MFD_CORE select MFD_WL1273_CORE select FW_LOADER diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index 97c2c18803ef..9cf6731fb816 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -375,7 +375,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq) if (r) return r; - INIT_COMPLETION(radio->busy); + reinit_completion(&radio->busy); /* wait for the FR IRQ */ r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); @@ -389,7 +389,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq) if (r) return r; - INIT_COMPLETION(radio->busy); + reinit_completion(&radio->busy); /* wait for the POWER_ENB IRQ */ r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); @@ -444,7 +444,7 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq) goto err; } - INIT_COMPLETION(radio->busy); + reinit_completion(&radio->busy); r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); if (!r) { @@ -805,7 +805,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio, if (level < SCHAR_MIN || level > SCHAR_MAX) return -EINVAL; - INIT_COMPLETION(radio->busy); + reinit_completion(&radio->busy); dev_dbg(radio->dev, "%s: BUSY\n", __func__); r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); @@ -847,7 +847,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio, if (r) goto out; - INIT_COMPLETION(radio->busy); + reinit_completion(&radio->busy); dev_dbg(radio->dev, "%s: BUSY\n", __func__); r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK); diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 5c57e5b0f949..0bd250068285 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -218,7 +218,7 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) goto done; /* wait till tune operation has completed */ - INIT_COMPLETION(radio->completion); + reinit_completion(&radio->completion); retval = wait_for_completion_timeout(&radio->completion, msecs_to_jiffies(tune_timeout)); if (!retval) @@ -341,7 +341,7 @@ static int si470x_set_seek(struct si470x_device *radio, return retval; /* wait till tune operation has completed */ - INIT_COMPLETION(radio->completion); + reinit_completion(&radio->completion); retval = wait_for_completion_timeout(&radio->completion, msecs_to_jiffies(seek_timeout)); if (!retval) diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 19632b1c2190..b53626ba6f49 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -207,7 +207,7 @@ static int iguanair_send(struct iguanair *ir, unsigned size) { int rc; - INIT_COMPLETION(ir->completion); + reinit_completion(&ir->completion); ir->urb_out->transfer_buffer_length = size; rc = usb_submit_urb(ir->urb_out, GFP_KERNEL); diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index ad9309da4a91..6c96e4898777 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -19,6 +19,7 @@ */ #include "e4000_priv.h" +#include <linux/math64.h> /* write multiple registers */ static int e4000_wr_regs(struct e4000_priv *priv, u8 reg, u8 *val, int len) @@ -233,7 +234,7 @@ static int e4000_set_params(struct dvb_frontend *fe) * or more. */ f_vco = c->frequency * e4000_pll_lut[i].mul; - sigma_delta = 0x10000UL * (f_vco % priv->cfg->clock) / priv->cfg->clock; + sigma_delta = div_u64(0x10000ULL * (f_vco % priv->cfg->clock), priv->cfg->clock); buf[0] = f_vco / priv->cfg->clock; buf[1] = (sigma_delta >> 0) & 0xff; buf[2] = (sigma_delta >> 8) & 0xff; diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index c43c8d32be40..be77482c3070 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -111,6 +111,13 @@ static const struct dmi_system_id stk_upside_down_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "F3JC") } }, + { + .ident = "T12Rg-H", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HCL Infosystems Limited"), + DMI_MATCH(DMI_PRODUCT_NAME, "T12Rg-H") + } + }, {} }; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 81695d48c13e..c3bb2502225b 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2090,6 +2090,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Microsoft Lifecam NX-3000 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x045e, + .idProduct = 0x0721, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_DEF }, /* Microsoft Lifecam VX-7000 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2174,6 +2183,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_DEF }, + /* Dell SP2008WFP Monitor */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x05a9, + .idProduct = 0x2641, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_DEF }, /* Dell Alienware X51 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 594c75eab5a5..de0e87f0b2c3 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -353,7 +353,9 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) if (b->m.planes[plane].bytesused > length) return -EINVAL; - if (b->m.planes[plane].data_offset >= + + if (b->m.planes[plane].data_offset > 0 && + b->m.planes[plane].data_offset >= b->m.planes[plane].bytesused) return -EINVAL; } diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index fd56f2563201..646f08f4f504 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -423,6 +423,39 @@ static inline int vma_is_io(struct vm_area_struct *vma) return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); } +static int vb2_dc_get_user_pfn(unsigned long start, int n_pages, + struct vm_area_struct *vma, unsigned long *res) +{ + unsigned long pfn, start_pfn, prev_pfn; + unsigned int i; + int ret; + + if (!vma_is_io(vma)) + return -EFAULT; + + ret = follow_pfn(vma, start, &pfn); + if (ret) + return ret; + + start_pfn = pfn; + start += PAGE_SIZE; + + for (i = 1; i < n_pages; ++i, start += PAGE_SIZE) { + prev_pfn = pfn; + ret = follow_pfn(vma, start, &pfn); + + if (ret) { + pr_err("no page for address %lu\n", start); + return ret; + } + if (pfn != prev_pfn + 1) + return -EINVAL; + } + + *res = start_pfn; + return 0; +} + static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, int n_pages, struct vm_area_struct *vma, int write) { @@ -433,6 +466,9 @@ static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, unsigned long pfn; int ret = follow_pfn(vma, start, &pfn); + if (!pfn_valid(pfn)) + return -EINVAL; + if (ret) { pr_err("no page for address %lu\n", start); return ret; @@ -468,16 +504,49 @@ static void vb2_dc_put_userptr(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); + if (sgt) { + dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + if (!vma_is_io(buf->vma)) + vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); - sg_free_table(sgt); - kfree(sgt); + sg_free_table(sgt); + kfree(sgt); + } vb2_put_vma(buf->vma); kfree(buf); } +/* + * For some kind of reserved memory there might be no struct page available, + * so all that can be done to support such 'pages' is to try to convert + * pfn to dma address or at the last resort just assume that + * dma address == physical address (like it has been assumed in earlier version + * of videobuf2-dma-contig + */ + +#ifdef __arch_pfn_to_dma +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__arch_pfn_to_dma(dev, pfn); +} +#elif defined(__pfn_to_bus) +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__pfn_to_bus(pfn); +} +#elif defined(__pfn_to_phys) +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__pfn_to_phys(pfn); +} +#else +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + /* really, we cannot do anything better at this point */ + return (dma_addr_t)(pfn) << PAGE_SHIFT; +} +#endif + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { @@ -548,6 +617,14 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, /* extract page list from userspace mapping */ ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write); if (ret) { + unsigned long pfn; + if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { + buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); + buf->size = size; + kfree(pages); + return buf; + } + pr_err("failed to get user pages\n"); goto fail_vma; } |