From 8b4aa4d8dc283a408eb14ca5e27e0a9a689c2e5a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 5 Apr 2018 12:03:05 -0400 Subject: media: mmp-camera.h: add missing platform data Those definitions used to be part of the original patch: https://patchwork.kernel.org/patch/2815221/ But, somehow, nobody ever noticed until today. Years later, Arnd discovered that mmp-camera driver doesn't build and make it depend on BROKEN. Add the missing bits here, in order to remove BROKEN dependency. Signed-off-by: Mauro Carvalho Chehab --- include/linux/platform_data/media/mmp-camera.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/linux/platform_data/media/mmp-camera.h b/include/linux/platform_data/media/mmp-camera.h index 83804028115c..d2d3a443eedf 100644 --- a/include/linux/platform_data/media/mmp-camera.h +++ b/include/linux/platform_data/media/mmp-camera.h @@ -3,8 +3,27 @@ * Information for the Marvell Armada MMP camera */ +#include + +enum dphy3_algo { + DPHY3_ALGO_DEFAULT = 0, + DPHY3_ALGO_PXA910, + DPHY3_ALGO_PXA2128 +}; + struct mmp_camera_platform_data { struct platform_device *i2c_device; int sensor_power_gpio; int sensor_reset_gpio; + enum v4l2_mbus_type bus_type; + int mclk_min; /* The minimal value of MCLK */ + int mclk_src; /* which clock source the MCLK derives from */ + int mclk_div; /* Clock Divider Value for MCLK */ + /* + * MIPI support + */ + int dphy[3]; /* DPHY: CSI2_DPHY3, CSI2_DPHY5, CSI2_DPHY6 */ + enum dphy3_algo dphy3_algo; /* algos for calculate CSI2_DPHY3 */ + int lane; /* ccic used lane number; 0 means DVP mode */ + int lane_clk; }; -- cgit v1.2.3-71-gd317 From 95d1544eb643847e05df06c3de252609593c9073 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 23 Mar 2018 16:59:52 -0400 Subject: media: rc: add ioctl to get the current timeout Since the kernel now modifies the timeout, make it possible to retrieve the current value. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/rc/lirc-func.rst | 1 + Documentation/media/uapi/rc/lirc-set-rec-timeout.rst | 14 +++++++++----- drivers/media/rc/lirc_dev.c | 7 +++++++ include/uapi/linux/lirc.h | 6 ++++++ 4 files changed, 23 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/rc/lirc-func.rst b/Documentation/media/uapi/rc/lirc-func.rst index ddb4620de294..9656423a3f28 100644 --- a/Documentation/media/uapi/rc/lirc-func.rst +++ b/Documentation/media/uapi/rc/lirc-func.rst @@ -17,6 +17,7 @@ LIRC Function Reference lirc-get-rec-resolution lirc-set-send-duty-cycle lirc-get-timeout + lirc-get-rec-timeout lirc-set-rec-timeout lirc-set-rec-carrier lirc-set-rec-carrier-range diff --git a/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst b/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst index b3e16bbdbc90..a833a6a4c25a 100644 --- a/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst +++ b/Documentation/media/uapi/rc/lirc-set-rec-timeout.rst @@ -1,19 +1,23 @@ .. -*- coding: utf-8; mode: rst -*- .. _lirc_set_rec_timeout: +.. _lirc_get_rec_timeout: -************************** -ioctl LIRC_SET_REC_TIMEOUT -************************** +*************************************************** +ioctl LIRC_GET_REC_TIMEOUT and LIRC_SET_REC_TIMEOUT +*************************************************** Name ==== -LIRC_SET_REC_TIMEOUT - sets the integer value for IR inactivity timeout. +LIRC_GET_REC_TIMEOUT/LIRC_SET_REC_TIMEOUT - Get/set the integer value for IR inactivity timeout. Synopsis ======== +.. c:function:: int ioctl( int fd, LIRC_GET_REC_TIMEOUT, __u32 *timeout ) + :name: LIRC_GET_REC_TIMEOUT + .. c:function:: int ioctl( int fd, LIRC_SET_REC_TIMEOUT, __u32 *timeout ) :name: LIRC_SET_REC_TIMEOUT @@ -30,7 +34,7 @@ Arguments Description =========== -Sets the integer value for IR inactivity timeout. +Get and set the integer value for IR inactivity timeout. If supported by the hardware, setting it to 0 disables all hardware timeouts and data should be reported as soon as possible. If the exact value diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 247e6fc3dc0c..6b4755e9fa25 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -575,6 +575,13 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, } break; + case LIRC_GET_REC_TIMEOUT: + if (!dev->timeout) + ret = -ENOTTY; + else + val = DIV_ROUND_UP(dev->timeout, 1000); + break; + case LIRC_SET_REC_TIMEOUT_REPORTS: if (!dev->timeout) ret = -ENOTTY; diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index f189931042a7..6b319581882f 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -133,6 +133,12 @@ #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) +/* + * Return the recording timeout, which is either set by + * the ioctl LIRC_SET_REC_TIMEOUT or by the kernel after setting the protocols. + */ +#define LIRC_GET_REC_TIMEOUT _IOR('i', 0x00000024, __u32) + /* * struct lirc_scancode - decoded scancode with protocol for use with * LIRC_MODE_SCANCODE -- cgit v1.2.3-71-gd317 From c7f1770f369ae0ec632b3ddc2bd6677b0e485128 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 5 Apr 2018 10:54:14 -0400 Subject: media: omap: omap-iommu.h: allow building drivers with COMPILE_TEST Drivers that depend on omap-iommu.h (currently, just omap3isp) need a stub implementation in order to be built with COMPILE_TEST. Acked-by: Sakari Ailus Acked-by: Hans Verkuil Acked-by: Arnd Bergmann Acked-by: Tony Lindgren Signed-off-by: Mauro Carvalho Chehab --- include/linux/omap-iommu.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h index c1aede46718b..ce1b7c6283ee 100644 --- a/include/linux/omap-iommu.h +++ b/include/linux/omap-iommu.h @@ -13,7 +13,12 @@ #ifndef _OMAP_IOMMU_H_ #define _OMAP_IOMMU_H_ +#ifdef CONFIG_OMAP_IOMMU extern void omap_iommu_save_ctx(struct device *dev); extern void omap_iommu_restore_ctx(struct device *dev); +#else +static inline void omap_iommu_save_ctx(struct device *dev) {} +static inline void omap_iommu_restore_ctx(struct device *dev) {} +#endif #endif -- cgit v1.2.3-71-gd317 From a2b2eff6ac2716f499defa590a6ec4ba379d765e Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Fri, 13 Apr 2018 14:34:31 -0400 Subject: media: v4l: fwnode: Fix comment incorrectly mentioning v4l2_fwnode_parse_endpoint It's called v4l2_fwnode_endpoint_parse, not v4l2_fwnode_parse_endpoint. Signed-off-by: Leonard Crestez Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-fwnode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index c228ec1c77cf..9cccab618b98 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -99,7 +99,7 @@ struct v4l2_fwnode_endpoint { struct fwnode_endpoint base; /* * Fields below this line will be zeroed by - * v4l2_fwnode_parse_endpoint() + * v4l2_fwnode_endpoint_parse() */ enum v4l2_mbus_type bus_type; union { -- cgit v1.2.3-71-gd317 From 771f7be87ff921e9a3d744febd606af39a150e14 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Apr 2018 13:42:51 -0400 Subject: media: omapfb: omapfb_dss.h: add stubs to build with COMPILE_TEST && DRM_OMAP Add stubs for omapfb_dss.h, in the case it is included by some driver when CONFIG_FB_OMAP2 is not defined, with can happen on ARM when DRM_OMAP is not 'n'. That allows building such driver(s) with COMPILE_TEST. Signed-off-by: Mauro Carvalho Chehab Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Mauro Carvalho Chehab --- include/video/omapfb_dss.h | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h index 1d38901d599d..e9775144ff3b 100644 --- a/include/video/omapfb_dss.h +++ b/include/video/omapfb_dss.h @@ -774,6 +774,12 @@ struct omap_dss_driver { const struct hdmi_avi_infoframe *avi); }; +#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL) + +typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); + +#ifdef CONFIG_FB_OMAP2 + enum omapdss_version omapdss_get_version(void); bool omapdss_is_initialized(void); @@ -785,7 +791,6 @@ void omapdss_unregister_display(struct omap_dss_device *dssdev); struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev); void omap_dss_put_device(struct omap_dss_device *dssdev); -#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL) struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); struct omap_dss_device *omap_dss_find_device(void *data, int (*match)(struct omap_dss_device *dssdev, void *data)); @@ -826,7 +831,6 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); void omapdss_default_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings); -typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask); int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask); @@ -856,5 +860,51 @@ omapdss_of_get_first_endpoint(const struct device_node *parent); struct omap_dss_device * omapdss_of_find_source_for_first_ep(struct device_node *node); +#else + +static inline enum omapdss_version omapdss_get_version(void) +{ return OMAPDSS_VER_UNKNOWN; }; + +static inline bool omapdss_is_initialized(void) +{ return false; }; + +static inline int omap_dispc_register_isr(omap_dispc_isr_t isr, + void *arg, u32 mask) +{ return 0; }; + +static inline int omap_dispc_unregister_isr(omap_dispc_isr_t isr, + void *arg, u32 mask) +{ return 0; }; + +static inline struct omap_dss_device +*omap_dss_get_device(struct omap_dss_device *dssdev) +{ return NULL; }; + +static inline struct omap_dss_device +*omap_dss_get_next_device(struct omap_dss_device *from) +{return NULL; }; + +static inline void omap_dss_put_device(struct omap_dss_device *dssdev) {}; + +static inline int omapdss_compat_init(void) +{ return 0; }; + +static inline void omapdss_compat_uninit(void) {}; + +static inline int omap_dss_get_num_overlay_managers(void) +{ return 0; }; + +static inline struct omap_overlay_manager *omap_dss_get_overlay_manager(int num) +{ return NULL; }; + +static inline int omap_dss_get_num_overlays(void) +{ return 0; }; + +static inline struct omap_overlay *omap_dss_get_overlay(int num) +{ return NULL; }; + + +#endif /* FB_OMAP2 */ + #endif /* __OMAPFB_DSS_H */ -- cgit v1.2.3-71-gd317 From adafae6229743fa1d99e2cc76fda7d964cea79f9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Mar 2018 03:30:48 -0500 Subject: media: v4l2-core: get rid of videobuf-dvb Videobuf has been replaced by videobuf2. Now, no drivers use the videobuf-dvb helper module anymore. So, get rid of it. Signed-off-by: Mauro Carvalho Chehab Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/Kconfig | 4 - drivers/media/v4l2-core/Makefile | 1 - drivers/media/v4l2-core/videobuf-dvb.c | 398 --------------------------------- include/media/videobuf-dvb.h | 59 ----- 4 files changed, 462 deletions(-) delete mode 100644 drivers/media/v4l2-core/videobuf-dvb.c delete mode 100644 include/media/videobuf-dvb.h (limited to 'include') diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 8e37e7c5e0f7..2a56f37f186b 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -76,7 +76,3 @@ config VIDEOBUF_DMA_CONTIG tristate depends on HAS_DMA select VIDEOBUF_GEN - -config VIDEOBUF_DVB - tristate - select VIDEOBUF_GEN diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 7df54582e956..9ee57e1efefe 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o -obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o ccflags-y += -I$(srctree)/drivers/media/dvb-frontends ccflags-y += -I$(srctree)/drivers/media/tuners diff --git a/drivers/media/v4l2-core/videobuf-dvb.c b/drivers/media/v4l2-core/videobuf-dvb.c deleted file mode 100644 index b7efa4516d36..000000000000 --- a/drivers/media/v4l2-core/videobuf-dvb.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * - * some helper function for simple DVB cards which simply DMA the - * complete transport stream and let the computer sort everything else - * (i.e. we are using the software demux, ...). Also uses the - * video-buf to manage DMA buffers. - * - * (c) 2004 Gerd Knorr [SUSE Labs] - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -/* ------------------------------------------------------------------ */ - -MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); -MODULE_LICENSE("GPL"); - -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"enable debug messages"); - -#define dprintk(fmt, arg...) if (debug) \ - printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name , ## arg) - -/* ------------------------------------------------------------------ */ - -static int videobuf_dvb_thread(void *data) -{ - struct videobuf_dvb *dvb = data; - struct videobuf_buffer *buf; - unsigned long flags; - void *outp; - - dprintk("dvb thread started\n"); - set_freezable(); - videobuf_read_start(&dvb->dvbq); - - for (;;) { - /* fetch next buffer */ - buf = list_entry(dvb->dvbq.stream.next, - struct videobuf_buffer, stream); - list_del(&buf->stream); - videobuf_waiton(&dvb->dvbq, buf, 0, 1); - - /* no more feeds left or stop_feed() asked us to quit */ - if (0 == dvb->nfeeds) - break; - if (kthread_should_stop()) - break; - try_to_freeze(); - - /* feed buffer data to demux */ - outp = videobuf_queue_to_vaddr(&dvb->dvbq, buf); - - if (buf->state == VIDEOBUF_DONE) - dvb_dmx_swfilter(&dvb->demux, outp, - buf->size); - - /* requeue buffer */ - list_add_tail(&buf->stream,&dvb->dvbq.stream); - spin_lock_irqsave(dvb->dvbq.irqlock,flags); - dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf); - spin_unlock_irqrestore(dvb->dvbq.irqlock,flags); - } - - videobuf_read_stop(&dvb->dvbq); - dprintk("dvb thread stopped\n"); - - /* Hmm, linux becomes *very* unhappy without this ... */ - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - } - return 0; -} - -static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct videobuf_dvb *dvb = demux->priv; - int rc; - - if (!demux->dmx.frontend) - return -EINVAL; - - mutex_lock(&dvb->lock); - dvb->nfeeds++; - rc = dvb->nfeeds; - - if (NULL != dvb->thread) - goto out; - dvb->thread = kthread_run(videobuf_dvb_thread, - dvb, "%s dvb", dvb->name); - if (IS_ERR(dvb->thread)) { - rc = PTR_ERR(dvb->thread); - dvb->thread = NULL; - } - -out: - mutex_unlock(&dvb->lock); - return rc; -} - -static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct videobuf_dvb *dvb = demux->priv; - int err = 0; - - mutex_lock(&dvb->lock); - dvb->nfeeds--; - if (0 == dvb->nfeeds && NULL != dvb->thread) { - err = kthread_stop(dvb->thread); - dvb->thread = NULL; - } - mutex_unlock(&dvb->lock); - return err; -} - -static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe, - struct module *module, - void *adapter_priv, - struct device *device, - char *adapter_name, - short *adapter_nr, - int mfe_shared) -{ - int result; - - mutex_init(&fe->lock); - - /* register adapter */ - result = dvb_register_adapter(&fe->adapter, adapter_name, module, - device, adapter_nr); - if (result < 0) { - printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", - adapter_name, result); - } - fe->adapter.priv = adapter_priv; - fe->adapter.mfe_shared = mfe_shared; - - return result; -} - -static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, - struct videobuf_dvb *dvb) -{ - int result; - - /* register frontend */ - result = dvb_register_frontend(adapter, dvb->frontend); - if (result < 0) { - printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", - dvb->name, result); - goto fail_frontend; - } - - /* register demux stuff */ - dvb->demux.dmx.capabilities = - DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING; - dvb->demux.priv = dvb; - dvb->demux.filternum = 256; - dvb->demux.feednum = 256; - dvb->demux.start_feed = videobuf_dvb_start_feed; - dvb->demux.stop_feed = videobuf_dvb_stop_feed; - result = dvb_dmx_init(&dvb->demux); - if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", - dvb->name, result); - goto fail_dmx; - } - - dvb->dmxdev.filternum = 256; - dvb->dmxdev.demux = &dvb->demux.dmx; - dvb->dmxdev.capabilities = 0; - result = dvb_dmxdev_init(&dvb->dmxdev, adapter); - - if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", - dvb->name, result); - goto fail_dmxdev; - } - - dvb->fe_hw.source = DMX_FRONTEND_0; - result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); - if (result < 0) { - printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", - dvb->name, result); - goto fail_fe_hw; - } - - dvb->fe_mem.source = DMX_MEMORY_FE; - result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); - if (result < 0) { - printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", - dvb->name, result); - goto fail_fe_mem; - } - - result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); - if (result < 0) { - printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", - dvb->name, result); - goto fail_fe_conn; - } - - /* register network adapter */ - result = dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx); - if (result < 0) { - printk(KERN_WARNING "%s: dvb_net_init failed (errno = %d)\n", - dvb->name, result); - goto fail_fe_conn; - } - return 0; - -fail_fe_conn: - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); -fail_fe_mem: - dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); -fail_fe_hw: - dvb_dmxdev_release(&dvb->dmxdev); -fail_dmxdev: - dvb_dmx_release(&dvb->demux); -fail_dmx: - dvb_unregister_frontend(dvb->frontend); -fail_frontend: - dvb_frontend_detach(dvb->frontend); - dvb->frontend = NULL; - - return result; -} - -/* ------------------------------------------------------------------ */ -/* Register a single adapter and one or more frontends */ -int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, - struct module *module, - void *adapter_priv, - struct device *device, - short *adapter_nr, - int mfe_shared) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe; - int res; - - fe = videobuf_dvb_get_frontend(f, 1); - if (!fe) { - printk(KERN_WARNING "Unable to register the adapter which has no frontends\n"); - return -EINVAL; - } - - /* Bring up the adapter */ - res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, - fe->dvb.name, adapter_nr, mfe_shared); - if (res < 0) { - printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res); - return res; - } - - /* Attach all of the frontends to the adapter */ - mutex_lock(&f->lock); - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb); - if (res < 0) { - printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n", - fe->dvb.name, res); - goto err; - } - } - mutex_unlock(&f->lock); - return 0; - -err: - mutex_unlock(&f->lock); - videobuf_dvb_unregister_bus(f); - return res; -} -EXPORT_SYMBOL(videobuf_dvb_register_bus); - -void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f) -{ - videobuf_dvb_dealloc_frontends(f); - - dvb_unregister_adapter(&f->adapter); -} -EXPORT_SYMBOL(videobuf_dvb_unregister_bus); - -struct videobuf_dvb_frontend *videobuf_dvb_get_frontend( - struct videobuf_dvb_frontends *f, int id) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe, *ret = NULL; - - mutex_lock(&f->lock); - - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->id == id) { - ret = fe; - break; - } - } - - mutex_unlock(&f->lock); - - return ret; -} -EXPORT_SYMBOL(videobuf_dvb_get_frontend); - -int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, - struct dvb_frontend *p) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe = NULL; - int ret = 0; - - mutex_lock(&f->lock); - - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->dvb.frontend == p) { - ret = fe->id; - break; - } - } - - mutex_unlock(&f->lock); - - return ret; -} -EXPORT_SYMBOL(videobuf_dvb_find_frontend); - -struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend( - struct videobuf_dvb_frontends *f, int id) -{ - struct videobuf_dvb_frontend *fe; - - fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL); - if (fe == NULL) - goto fail_alloc; - - fe->id = id; - mutex_init(&fe->dvb.lock); - - mutex_lock(&f->lock); - list_add_tail(&fe->felist, &f->felist); - mutex_unlock(&f->lock); - -fail_alloc: - return fe; -} -EXPORT_SYMBOL(videobuf_dvb_alloc_frontend); - -void videobuf_dvb_dealloc_frontends(struct videobuf_dvb_frontends *f) -{ - struct list_head *list, *q; - struct videobuf_dvb_frontend *fe; - - mutex_lock(&f->lock); - list_for_each_safe(list, q, &f->felist) { - fe = list_entry(list, struct videobuf_dvb_frontend, felist); - if (fe->dvb.net.dvbdev) { - dvb_net_release(&fe->dvb.net); - fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, - &fe->dvb.fe_mem); - fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, - &fe->dvb.fe_hw); - dvb_dmxdev_release(&fe->dvb.dmxdev); - dvb_dmx_release(&fe->dvb.demux); - dvb_unregister_frontend(fe->dvb.frontend); - } - if (fe->dvb.frontend) - /* always allocated, may have been reset */ - dvb_frontend_detach(fe->dvb.frontend); - list_del(list); /* remove list entry */ - kfree(fe); /* free frontend allocation */ - } - mutex_unlock(&f->lock); -} -EXPORT_SYMBOL(videobuf_dvb_dealloc_frontends); diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h deleted file mode 100644 index c9c81990a56c..000000000000 --- a/include/media/videobuf-dvb.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include -#include -#include - -#ifndef _VIDEOBUF_DVB_H_ -#define _VIDEOBUF_DVB_H_ - -struct videobuf_dvb { - /* filling that the job of the driver */ - char *name; - struct dvb_frontend *frontend; - struct videobuf_queue dvbq; - - /* video-buf-dvb state info */ - struct mutex lock; - struct task_struct *thread; - int nfeeds; - - /* videobuf_dvb_(un)register manges this */ - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dmx_frontend fe_hw; - struct dmx_frontend fe_mem; - struct dvb_net net; -}; - -struct videobuf_dvb_frontend { - struct list_head felist; - int id; - struct videobuf_dvb dvb; -}; - -struct videobuf_dvb_frontends { - struct list_head felist; - struct mutex lock; - struct dvb_adapter adapter; - int active_fe_id; /* Indicates which frontend in the felist is in use */ - int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */ -}; - -int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f, - struct module *module, - void *adapter_priv, - struct device *device, - short *adapter_nr, - int mfe_shared); - -void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f); - -struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id); -void videobuf_dvb_dealloc_frontends(struct videobuf_dvb_frontends *f); - -struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id); -int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p); - -#endif /* _VIDEOBUF_DVB_H_ */ -- cgit v1.2.3-71-gd317 From 5b1a270d224b77551ea50b613155619847d3d154 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Sun, 18 Mar 2018 08:40:16 -0400 Subject: media: dvb: add alternative USB PID for Hauppauge WinTV-soloHD Newer DVB receivers of this type have a different USB PID. Signed-off-by: Rainer Keller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 2 ++ include/media/dvb-usb-ids.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include') diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 6e0e67d23876..fd4bde048dd9 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2663,6 +2663,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PCTV_292E }, { USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */ .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x2040, 0x8268), /* Hauppauge WinTV-soloHD alt. PID */ + .driver_info = EM28178_BOARD_PCTV_292E }, { USB_DEVICE(0x0413, 0x6f07), .driver_info = EM2861_BOARD_LEADTEK_VC100 }, { USB_DEVICE(0xeb1a, 0x8179), diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h index 28e2be5c8a98..f9e73b4a6e89 100644 --- a/include/media/dvb-usb-ids.h +++ b/include/media/dvb-usb-ids.h @@ -418,6 +418,7 @@ #define USB_PID_SVEON_STV27 0xd3af #define USB_PID_TURBOX_DTT_2000 0xd3a4 #define USB_PID_WINTV_SOLOHD 0x0264 +#define USB_PID_WINTV_SOLOHD_2 0x8268 #define USB_PID_EVOLVEO_XTRATV_STICK 0xa115 #define USB_PID_HAMA_DVBT_HYBRID 0x2758 #define USB_PID_XBOX_ONE_TUNER 0x02d5 -- cgit v1.2.3-71-gd317 From 6159e12e11770fb25e748af90f6c5206c1df09ee Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Apr 2018 11:55:13 -0400 Subject: media: meye: allow building it with COMPILE_TEST on non-x86 This driver depends on sony-laptop driver, but this is available only for x86. So, add a stub function, in order to allow building it on non-x86 too. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/meye/Kconfig | 3 ++- include/linux/sony-laptop.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/media/pci/meye/Kconfig b/drivers/media/pci/meye/Kconfig index b4bf848be5a0..2e60334ffef5 100644 --- a/drivers/media/pci/meye/Kconfig +++ b/drivers/media/pci/meye/Kconfig @@ -1,6 +1,7 @@ config VIDEO_MEYE tristate "Sony Vaio Picturebook Motion Eye Video For Linux" - depends on PCI && SONY_LAPTOP && VIDEO_V4L2 + depends on PCI && VIDEO_V4L2 + depends on SONY_LAPTOP || COMPILE_TEST ---help--- This is the video4linux driver for the Motion Eye camera found in the Vaio Picturebook laptops. Please read the material in diff --git a/include/linux/sony-laptop.h b/include/linux/sony-laptop.h index 1a4b77317fa1..374d0fdb0743 100644 --- a/include/linux/sony-laptop.h +++ b/include/linux/sony-laptop.h @@ -28,7 +28,11 @@ #define SONY_PIC_COMMAND_GETCAMERAROMVERSION 18 /* obsolete */ #define SONY_PIC_COMMAND_GETCAMERAREVISION 19 /* obsolete */ +#if IS_ENABLED(CONFIG_SONY_LAPTOP) int sony_pic_camera_command(int command, u8 value); +#else +static inline int sony_pic_camera_command(int command, u8 value) { return 0; }; +#endif #endif /* __KERNEL__ */ -- cgit v1.2.3-71-gd317 From f10379aad39e9da8bc7d1822e251b5f0673067ef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 May 2018 16:49:32 -0400 Subject: media: include/video/omapfb_dss.h: use IS_ENABLED() Just checking for ifdefs cause build issues as reported by kernel test: config: openrisc-allmodconfig (attached as .config) compiler: or1k-linux-gcc (GCC) 6.0.0 20160327 (experimental) All errors (new ones prefixed by >>): drivers/video/fbdev/omap2/omapfb/omapfb-main.c: In function 'omapfb_init_connections': >> drivers/video/fbdev/omap2/omapfb/omapfb-main.c:2396:8: error: implicit declaration of function 'omapdss_find_mgr_from_display' [-Werror=implicit-function-declaration] mgr = omapdss_find_mgr_from_display(def_dssdev); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/video/fbdev/omap2/omapfb/omapfb-main.c:2396:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion] mgr = omapdss_find_mgr_from_display(def_dssdev); ^ drivers/video/fbdev/omap2/omapfb/omapfb-main.c: In function 'omapfb_find_default_display': >> drivers/video/fbdev/omap2/omapfb/omapfb-main.c:2430:13: error: implicit declaration of function 'omapdss_get_default_display_name' [-Werror=implicit-function-declaration] def_name = omapdss_get_default_display_name(); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/video/fbdev/omap2/omapfb/omapfb-main.c:2430:11: warning: assignment makes pointer from integer without a cast [-Wint-conversion] def_name = omapdss_get_default_display_name(); ^ So, use IS_ENABLED() instead. Fixes: 771f7be87ff9 ("media: omapfb: omapfb_dss.h: add stubs to build with COMPILE_TEST && DRM_OMAP") Cc: Bartlomiej Zolnierkiewicz Cc: Randy Dunlap Cc: tomi.valkeinen@ti.com Cc: linux-omap@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- include/video/omapfb_dss.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h index e9775144ff3b..12755d8d9b4f 100644 --- a/include/video/omapfb_dss.h +++ b/include/video/omapfb_dss.h @@ -778,7 +778,7 @@ struct omap_dss_driver { typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); -#ifdef CONFIG_FB_OMAP2 +#if IS_ENABLED(CONFIG_FB_OMAP2) enum omapdss_version omapdss_get_version(void); bool omapdss_is_initialized(void); -- cgit v1.2.3-71-gd317 From f0a3fa2149e36cc2426bcb13a8bdcdbe592a6d2d Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Sun, 8 Apr 2018 12:11:52 -0400 Subject: media: entity: fix spelling for media_entity_get_fwnode_pad() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s/dose/does/ Fixes: d295c6a460cd2ac6 ("[media] media: entity: Add media_entity_get_fwnode_pad() function") Signed-off-by: Niklas Söderlund Reviewed-by: Simon Horman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a732af1dbba0..3aa3d58d1d58 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -842,7 +842,7 @@ struct media_entity *media_entity_get(struct media_entity *entity); * a fwnode. This is useful for devices which use more complex * mappings of media pads. * - * If the entity dose not implement the get_fwnode_pad() operation + * If the entity does not implement the get_fwnode_pad() operation * then this function searches the entity for the first pad that * matches the @direction_flags. * -- cgit v1.2.3-71-gd317 From 5bc3744c38e75f169b0e7eefebe033e2937fd71c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 3 May 2018 08:47:10 -0400 Subject: media: v4l2-dev.h: fix doc warning Fix this warning when building the docs: include/media/v4l2-dev.h:42: warning: Enum value 'VFL_TYPE_MAX' not described in enum 'vfl_devnode_type' Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index f60cf9cf3b9c..73073f6ee48c 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -30,6 +30,7 @@ * @VFL_TYPE_SUBDEV: for V4L2 subdevices * @VFL_TYPE_SDR: for Software Defined Radio tuners * @VFL_TYPE_TOUCH: for touch sensors + * @VFL_TYPE_MAX: number of VFL types, must always be last in the enum */ enum vfl_devnode_type { VFL_TYPE_GRABBER = 0, -- cgit v1.2.3-71-gd317 From 378e3f81cb5653b28100d3231db6da07b0581ff4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 25 Apr 2018 17:30:10 -0400 Subject: media: omap3isp: support 64-bit version of omap3isp_stat_data C libraries with 64-bit time_t use an incompatible format for struct omap3isp_stat_data. This changes the kernel code to support either version, by moving over the normal handling to the 64-bit variant, and adding compatiblity code to handle the old binary format with the existing ioctl command code. Fortunately, the command code includes the size of the structure, so the difference gets handled automatically. In the process of eliminating the references to 'struct timeval' from the kernel, I also change the way the timestamp is generated internally, basically by open-coding the v4l2_get_timestamp() call. [Sakari Ailus: Alphabetical order of headers, clean up compat code] Cc: Sakari Ailus Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isph3a_aewb.c | 2 ++ drivers/media/platform/omap3isp/isph3a_af.c | 2 ++ drivers/media/platform/omap3isp/isphist.c | 2 ++ drivers/media/platform/omap3isp/ispstat.c | 23 +++++++++++++++++++++-- drivers/media/platform/omap3isp/ispstat.h | 4 +++- include/uapi/linux/omap3isp.h | 22 ++++++++++++++++++++++ 6 files changed, 52 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/media/platform/omap3isp/isph3a_aewb.c b/drivers/media/platform/omap3isp/isph3a_aewb.c index d44626f20ac6..3c82dea4d375 100644 --- a/drivers/media/platform/omap3isp/isph3a_aewb.c +++ b/drivers/media/platform/omap3isp/isph3a_aewb.c @@ -250,6 +250,8 @@ static long h3a_aewb_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return omap3isp_stat_config(stat, arg); case VIDIOC_OMAP3ISP_STAT_REQ: return omap3isp_stat_request_statistics(stat, arg); + case VIDIOC_OMAP3ISP_STAT_REQ_TIME32: + return omap3isp_stat_request_statistics_time32(stat, arg); case VIDIOC_OMAP3ISP_STAT_EN: { unsigned long *en = arg; return omap3isp_stat_enable(stat, !!*en); diff --git a/drivers/media/platform/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c index 99bd6cc21d86..4da25c84f0c6 100644 --- a/drivers/media/platform/omap3isp/isph3a_af.c +++ b/drivers/media/platform/omap3isp/isph3a_af.c @@ -314,6 +314,8 @@ static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return omap3isp_stat_config(stat, arg); case VIDIOC_OMAP3ISP_STAT_REQ: return omap3isp_stat_request_statistics(stat, arg); + case VIDIOC_OMAP3ISP_STAT_REQ_TIME32: + return omap3isp_stat_request_statistics_time32(stat, arg); case VIDIOC_OMAP3ISP_STAT_EN: { int *en = arg; return omap3isp_stat_enable(stat, !!*en); diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c index a4ed5d140d48..d4be3d0e06f9 100644 --- a/drivers/media/platform/omap3isp/isphist.c +++ b/drivers/media/platform/omap3isp/isphist.c @@ -435,6 +435,8 @@ static long hist_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return omap3isp_stat_config(stat, arg); case VIDIOC_OMAP3ISP_STAT_REQ: return omap3isp_stat_request_statistics(stat, arg); + case VIDIOC_OMAP3ISP_STAT_REQ_TIME32: + return omap3isp_stat_request_statistics_time32(stat, arg); case VIDIOC_OMAP3ISP_STAT_EN: { int *en = arg; return omap3isp_stat_enable(stat, !!*en); diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index 0b31f6c5791f..6af7460a3559 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "isp.h" @@ -237,7 +238,7 @@ static int isp_stat_buf_queue(struct ispstat *stat) if (!stat->active_buf) return STAT_NO_BUF; - v4l2_get_timestamp(&stat->active_buf->ts); + ktime_get_ts64(&stat->active_buf->ts); stat->active_buf->buf_size = stat->buf_size; if (isp_stat_buf_check_magic(stat, stat->active_buf)) { @@ -498,7 +499,8 @@ int omap3isp_stat_request_statistics(struct ispstat *stat, return PTR_ERR(buf); } - data->ts = buf->ts; + data->ts.tv_sec = buf->ts.tv_sec; + data->ts.tv_usec = buf->ts.tv_nsec / NSEC_PER_USEC; data->config_counter = buf->config_counter; data->frame_number = buf->frame_number; data->buf_size = buf->buf_size; @@ -510,6 +512,23 @@ int omap3isp_stat_request_statistics(struct ispstat *stat, return 0; } +int omap3isp_stat_request_statistics_time32(struct ispstat *stat, + struct omap3isp_stat_data_time32 *data) +{ + struct omap3isp_stat_data data64; + int ret; + + ret = omap3isp_stat_request_statistics(stat, &data64); + if (ret) + return ret; + + data->ts.tv_sec = data64.ts.tv_sec; + data->ts.tv_usec = data64.ts.tv_usec; + memcpy(&data->buf, &data64.buf, sizeof(*data) - sizeof(data->ts)); + + return 0; +} + /* * omap3isp_stat_config - Receives new statistic engine configuration. * @new_conf: Pointer to config structure. diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h index 6d9b0244f320..923b38cfc682 100644 --- a/drivers/media/platform/omap3isp/ispstat.h +++ b/drivers/media/platform/omap3isp/ispstat.h @@ -39,7 +39,7 @@ struct ispstat_buffer { struct sg_table sgt; void *virt_addr; dma_addr_t dma_addr; - struct timeval ts; + struct timespec64 ts; u32 buf_size; u32 frame_number; u16 config_counter; @@ -130,6 +130,8 @@ struct ispstat_generic_config { int omap3isp_stat_config(struct ispstat *stat, void *new_conf); int omap3isp_stat_request_statistics(struct ispstat *stat, struct omap3isp_stat_data *data); +int omap3isp_stat_request_statistics_time32(struct ispstat *stat, + struct omap3isp_stat_data_time32 *data); int omap3isp_stat_init(struct ispstat *stat, const char *name, const struct v4l2_subdev_ops *sd_ops); void omap3isp_stat_cleanup(struct ispstat *stat); diff --git a/include/uapi/linux/omap3isp.h b/include/uapi/linux/omap3isp.h index 1a920145db04..87b55755f4ff 100644 --- a/include/uapi/linux/omap3isp.h +++ b/include/uapi/linux/omap3isp.h @@ -55,6 +55,8 @@ _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct omap3isp_h3a_af_config) #define VIDIOC_OMAP3ISP_STAT_REQ \ _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct omap3isp_stat_data) +#define VIDIOC_OMAP3ISP_STAT_REQ_TIME32 \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct omap3isp_stat_data_time32) #define VIDIOC_OMAP3ISP_STAT_EN \ _IOWR('V', BASE_VIDIOC_PRIVATE + 7, unsigned long) @@ -165,7 +167,14 @@ struct omap3isp_h3a_aewb_config { * @config_counter: Number of the configuration associated with the data. */ struct omap3isp_stat_data { +#ifdef __KERNEL__ + struct { + __s64 tv_sec; + __s64 tv_usec; + } ts; +#else struct timeval ts; +#endif void __user *buf; __u32 buf_size; __u16 frame_number; @@ -173,6 +182,19 @@ struct omap3isp_stat_data { __u16 config_counter; }; +#ifdef __KERNEL__ +struct omap3isp_stat_data_time32 { + struct { + __s32 tv_sec; + __s32 tv_usec; + } ts; + __u32 buf; + __u32 buf_size; + __u16 frame_number; + __u16 cur_frame; + __u16 config_counter; +}; +#endif /* Histogram related structs */ -- cgit v1.2.3-71-gd317 From acd14c181fc201a397aaff02af3b8c3f1dcf233f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 3 May 2018 10:52:51 -0400 Subject: media: v4l2-device.h: always expose mdev The mdev field is only present if CONFIG_MEDIA_CONTROLLER is set. But since we will need to pass the media_device to vb2 and the control framework it is very convenient to just make this field available all the time. If CONFIG_MEDIA_CONTROLLER is not set, then it will just be NULL. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-device.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 0c9e4da55499..b330e4a08a6b 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -33,7 +33,7 @@ struct v4l2_ctrl_handler; * struct v4l2_device - main struct to for V4L2 device drivers * * @dev: pointer to struct device. - * @mdev: pointer to struct media_device + * @mdev: pointer to struct media_device, may be NULL. * @subdevs: used to keep track of the registered subdevs * @lock: lock this struct; can be used by the driver as well * if this struct is embedded into a larger struct. @@ -58,9 +58,7 @@ struct v4l2_ctrl_handler; */ struct v4l2_device { struct device *dev; -#if defined(CONFIG_MEDIA_CONTROLLER) struct media_device *mdev; -#endif struct list_head subdevs; spinlock_t lock; char name[V4L2_DEVICE_NAME_SIZE]; -- cgit v1.2.3-71-gd317 From f17c403af9bf3dc19069cb8c10390030ee4c8fb0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 3 May 2018 14:12:59 -0400 Subject: media: dvbdev: add a mutex protecting the "mdev" pointer During destruction, a race condition in dvb_media_controller_disable_source() can cause a kernel crash, because the "mdev" pointer has been read successfully while another task executes dvb_usb_media_device_unregister(), which destroys the object. Example for such a crash: general protection fault: 0000 [#1] SMP CPU: 1 PID: 301 Comm: vdr Not tainted 4.8.1-nuc+ #102 [142B blob data] task: ffff8802301f2040 task.stack: ffff880233728000 RIP: 0010:[] [] dvb_frontend_release+0xcb/0x120 RSP: 0018:ffff88023372bdd8 EFLAGS: 00010202 RAX: 001fd55c000000da RBX: ffff880236bad810 RCX: 0000000000000000 RDX: ffff880235bd81f0 RSI: 0000000000000246 RDI: ffff880235bd81e8 RBP: ffff88023372be00 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: ffff88022f009910 R12: 0000000000000000 R13: ffff880235a21a80 R14: ffff880235bd8000 R15: ffff880235bb8a78 FS: 0000000000000000(0000) GS:ffff88023fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f96edd69818 CR3: 0000000002406000 CR4: 00000000001006e0 Stack: ffff88022f009900 0000000000000008 ffff880235bb8a78 ffff8802344fbb20 ffff880236437b40 ffff88023372be48 ffffffff8117a81e ffff880235bb8a78 ffff88022f009910 ffff8802335a7400 ffff8802301f2040 ffff88022f009900 Call Trace: [] __fput+0xde/0x1d0 [] ____fput+0x9/0x10 [] task_work_run+0x7e/0xa0 [] do_exit+0x27b/0xa50 [] ? __do_page_fault+0x1c3/0x430 [] do_group_exit+0x42/0xb0 [] SyS_exit_group+0xf/0x10 [] entry_SYSCALL_64_fastpath+0x13/0x8f Code: 31 c9 49 8d be e8 01 00 00 ba 01 00 00 00 be 03 00 00 00 e8 68 2d a0 ff 48 8b 83 10 03 00 00 48 8b 80 88 00 00 00 48 85 c0 74 12 <48> 8b 80 88 02 00 00 48 85 c0 74 06 49 8b 7d RIP [] dvb_frontend_release+0xcb/0x120 [mchehab+samsung@kernel.org: fix a Coding Style issue] Signed-off-by: Max Kellermann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 7 +++++++ drivers/media/dvb-core/dvbdev.c | 4 ++++ drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 4 ++++ include/media/dvbdev.h | 2 ++ 4 files changed, 17 insertions(+) (limited to 'include') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index bc5eaad0f915..f64141662a82 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2732,6 +2732,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) fepriv->voltage = -1; #ifdef CONFIG_MEDIA_CONTROLLER_DVB + mutex_lock(&fe->dvb->mdev_lock); if (fe->dvb->mdev) { mutex_lock(&fe->dvb->mdev->graph_mutex); if (fe->dvb->mdev->enable_source) @@ -2740,11 +2741,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) &fepriv->pipe); mutex_unlock(&fe->dvb->mdev->graph_mutex); if (ret) { + mutex_unlock(&fe->dvb->mdev_lock); dev_err(fe->dvb->device, "Tuner is busy. Error %d\n", ret); goto err2; } } + mutex_unlock(&fe->dvb->mdev_lock); #endif ret = dvb_frontend_start (fe); if (ret) @@ -2762,12 +2765,14 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) err3: #ifdef CONFIG_MEDIA_CONTROLLER_DVB + mutex_lock(&fe->dvb->mdev_lock); if (fe->dvb->mdev) { mutex_lock(&fe->dvb->mdev->graph_mutex); if (fe->dvb->mdev->disable_source) fe->dvb->mdev->disable_source(dvbdev->entity); mutex_unlock(&fe->dvb->mdev->graph_mutex); } + mutex_unlock(&fe->dvb->mdev_lock); err2: #endif dvb_generic_release(inode, file); @@ -2799,12 +2804,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) if (dvbdev->users == -1) { wake_up(&fepriv->wait_queue); #ifdef CONFIG_MEDIA_CONTROLLER_DVB + mutex_lock(&fe->dvb->mdev_lock); if (fe->dvb->mdev) { mutex_lock(&fe->dvb->mdev->graph_mutex); if (fe->dvb->mdev->disable_source) fe->dvb->mdev->disable_source(dvbdev->entity); mutex_unlock(&fe->dvb->mdev->graph_mutex); } + mutex_unlock(&fe->dvb->mdev_lock); #endif if (fe->exit != DVB_FE_NO_EXIT) wake_up(&dvbdev->wait_queue); diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 787fe06df217..64d6793674b9 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -859,6 +859,10 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, adap->mfe_dvbdev = NULL; mutex_init (&adap->mfe_lock); +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + mutex_init(&adap->mdev_lock); +#endif + list_add_tail (&adap->list_head, &dvb_adapter_list); mutex_unlock(&dvbdev_register_lock); diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 3a66e732e0d8..8056053c9ab0 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -132,10 +132,14 @@ static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap) if (!adap->dvb_adap.mdev) return; + mutex_lock(&adap->dvb_adap.mdev_lock); + media_device_unregister(adap->dvb_adap.mdev); media_device_cleanup(adap->dvb_adap.mdev); kfree(adap->dvb_adap.mdev); adap->dvb_adap.mdev = NULL; + + mutex_unlock(&adap->dvb_adap.mdev_lock); #endif } diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h index ee91516ad074..881ca461b7bb 100644 --- a/include/media/dvbdev.h +++ b/include/media/dvbdev.h @@ -91,6 +91,7 @@ struct dvb_frontend; * @mfe_dvbdev: Frontend device in use, in the case of MFE * @mfe_lock: Lock to prevent using the other frontends when MFE is * used. + * @mdev_lock: Protect access to the mdev pointer. * @mdev: pointer to struct media_device, used when the media * controller is used. * @conn: RF connector. Used only if the device has no separate @@ -114,6 +115,7 @@ struct dvb_adapter { struct mutex mfe_lock; /* access lock for thread creation */ #if defined(CONFIG_MEDIA_CONTROLLER_DVB) + struct mutex mdev_lock; struct media_device *mdev; struct media_entity *conn; struct media_pad *conn_pads; -- cgit v1.2.3-71-gd317 From e0d51e6ceff818c5d7a812c26bbd1bb84348a71a Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 10 May 2018 16:41:15 -0400 Subject: media: rc: default to idle on at startup or after reset Any spaces events received after a reset or startup should be discarded, so ensure the rc device is in idle mode. This also makes it much easier to detect incorrect raw events, as we will do in a following commit. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-ir-raw.c | 1 + include/media/rc-core.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 2ab8a2b7092a..2e50104ae138 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -611,6 +611,7 @@ int ir_raw_event_prepare(struct rc_dev *dev) dev->raw->dev = dev; dev->change_protocol = change_protocol; + dev->idle = true; spin_lock_init(&dev->raw->edge_spinlock); timer_setup(&dev->raw->edge_handle, ir_raw_edge_handle, 0); INIT_KFIFO(dev->raw->kfifo); diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 6742fd86ff65..61571773a98d 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -347,6 +347,7 @@ static inline void ir_raw_event_reset(struct rc_dev *dev) struct ir_raw_event ev = { .reset = true }; ir_raw_event_store(dev, &ev); + dev->idle = true; ir_raw_event_handle(dev); } -- cgit v1.2.3-71-gd317 From 0d93d5c915d5b8a7f74f6d3e59748c06adcf6e9f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Nov 2017 11:32:18 -0500 Subject: media: v4l: vsp1: Document the vsp1_du_atomic_config structure The structure is used in the API that the VSP1 driver exposes to the DU driver. Documenting it is thus important. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 68a8abe4fac5..ff7ef894465d 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -41,6 +41,16 @@ struct vsp1_du_lif_config { int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, const struct vsp1_du_lif_config *cfg); +/** + * struct vsp1_du_atomic_config - VSP atomic configuration parameters + * @pixelformat: plane pixel format (V4L2 4CC) + * @pitch: line pitch in bytes, for all planes + * @mem: DMA memory address for each plane of the frame buffer + * @src: source rectangle in the frame buffer (integer coordinates) + * @dst: destination rectangle on the display (integer coordinates) + * @alpha: alpha value (0: fully transparent, 255: fully opaque) + * @zpos: Z position of the plane (from 0 to number of planes minus 1) + */ struct vsp1_du_atomic_config { u32 pixelformat; unsigned int pitch; -- cgit v1.2.3-71-gd317 From 6e274b43b5730f53029354fc10c0beabefed60e2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 1 Dec 2017 06:47:19 -0500 Subject: media: v4l: vsp1: Extend the DU API to support CRC computation Add a parameter (in the form of a structure to ease future API extensions) to the VSP atomic flush handler to pass CRC source configuration, and pass the CRC value to the completion callback. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 6 ++++-- drivers/media/platform/vsp1/vsp1_drm.c | 6 ++++-- drivers/media/platform/vsp1/vsp1_drm.h | 2 +- include/media/vsp1.h | 35 ++++++++++++++++++++++++++++++++-- 4 files changed, 42 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 2c260c33840b..bdcec201591f 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -31,7 +31,7 @@ #include "rcar_du_kms.h" #include "rcar_du_vsp.h" -static void rcar_du_vsp_complete(void *private, bool completed) +static void rcar_du_vsp_complete(void *private, bool completed, u32 crc) { struct rcar_du_crtc *crtc = private; @@ -102,7 +102,9 @@ void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc) { - vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe); + struct vsp1_du_atomic_pipe_config cfg = { { 0, } }; + + vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe, &cfg); } /* Keep the two tables in sync. */ diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 2b29a83dceb9..5fc31578f9b0 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -36,7 +36,7 @@ static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe, bool complete = completion == VSP1_DL_FRAME_END_COMPLETED; if (drm_pipe->du_complete) - drm_pipe->du_complete(drm_pipe->du_private, complete); + drm_pipe->du_complete(drm_pipe->du_private, complete, 0); if (completion & VSP1_DL_FRAME_END_INTERNAL) { drm_pipe->force_brx_release = false; @@ -739,8 +739,10 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_update); * vsp1_du_atomic_flush - Commit an atomic update * @dev: the VSP device * @pipe_index: the DRM pipeline index + * @cfg: atomic pipe configuration */ -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index, + const struct vsp1_du_atomic_pipe_config *cfg) { struct vsp1_device *vsp1 = dev_get_drvdata(dev); struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index]; diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h index f4af1b2b12d6..e5b88b28806c 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.h +++ b/drivers/media/platform/vsp1/vsp1_drm.h @@ -35,7 +35,7 @@ struct vsp1_drm_pipeline { wait_queue_head_t wait_queue; /* Frame synchronisation */ - void (*du_complete)(void *, bool); + void (*du_complete)(void *data, bool completed, u32 crc); void *du_private; }; diff --git a/include/media/vsp1.h b/include/media/vsp1.h index ff7ef894465d..678c24de1ac6 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -34,7 +34,7 @@ struct vsp1_du_lif_config { unsigned int width; unsigned int height; - void (*callback)(void *, bool); + void (*callback)(void *data, bool completed, u32 crc); void *callback_data; }; @@ -61,11 +61,42 @@ struct vsp1_du_atomic_config { unsigned int zpos; }; +/** + * enum vsp1_du_crc_source - Source used for CRC calculation + * @VSP1_DU_CRC_NONE: CRC calculation disabled + * @VSP1_DU_CRC_PLANE: Perform CRC calculation on an input plane + * @VSP1_DU_CRC_OUTPUT: Perform CRC calculation on the composed output + */ +enum vsp1_du_crc_source { + VSP1_DU_CRC_NONE, + VSP1_DU_CRC_PLANE, + VSP1_DU_CRC_OUTPUT, +}; + +/** + * struct vsp1_du_crc_config - VSP CRC computation configuration parameters + * @source: source for CRC calculation + * @index: index of the CRC source plane (when source is set to plane) + */ +struct vsp1_du_crc_config { + enum vsp1_du_crc_source source; + unsigned int index; +}; + +/** + * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters + * @crc: CRC computation configuration + */ +struct vsp1_du_atomic_pipe_config { + struct vsp1_du_crc_config crc; +}; + void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index); int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, unsigned int rpf, const struct vsp1_du_atomic_config *cfg); -void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index); +void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index, + const struct vsp1_du_atomic_pipe_config *cfg); int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt); void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt); -- cgit v1.2.3-71-gd317 From 0d5615d3479fd165a4aca7f2dc3c418ffed3eb20 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 12 May 2018 10:44:03 -0400 Subject: media: v4l2-ioctl: delete unused v4l2_disable_ioctl_locking The last user of this 'feature' was the gspca driver. Now that that driver has been converted to vb2 we can delete this code. Signed-off-by: Hans Verkuil Reviewed-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 -- include/media/v4l2-dev.h | 15 --------------- 2 files changed, 17 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 212aac1d22c1..c23fbfe90a9e 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2666,8 +2666,6 @@ struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd) { if (_IOC_NR(cmd) >= V4L2_IOCTLS) return vdev->lock; - if (test_bit(_IOC_NR(cmd), vdev->disable_locking)) - return NULL; if (vdev->queue && vdev->queue->lock && (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) return vdev->queue->lock; diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 73073f6ee48c..30423aefe7c5 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -238,7 +238,6 @@ struct v4l2_file_operations { * @ioctl_ops: pointer to &struct v4l2_ioctl_ops with ioctl callbacks * * @valid_ioctls: bitmap with the valid ioctls for this device - * @disable_locking: bitmap with the ioctls that don't require locking * @lock: pointer to &struct mutex serialization lock * * .. note:: @@ -291,7 +290,6 @@ struct video_device const struct v4l2_ioctl_ops *ioctl_ops; DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); - DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE); struct mutex *lock; }; @@ -446,19 +444,6 @@ void video_device_release_empty(struct video_device *vdev); */ bool v4l2_is_known_ioctl(unsigned int cmd); -/** v4l2_disable_ioctl_locking - mark that a given command - * shouldn't use core locking - * - * @vdev: pointer to &struct video_device - * @cmd: ioctl command - */ -static inline void v4l2_disable_ioctl_locking(struct video_device *vdev, - unsigned int cmd) -{ - if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) - set_bit(_IOC_NR(cmd), vdev->disable_locking); -} - /** * v4l2_disable_ioctl- mark that a given command isn't implemented. * shouldn't use core locking -- cgit v1.2.3-71-gd317 From 73a110623e7b7592defea69f028cccae495d69a4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 11 May 2018 05:32:24 -0400 Subject: media: v4l2-core: push taking ioctl mutex down to ioctl handler The ioctl serialization mutex (vdev->lock or q->lock for vb2 queues) was taken at the highest level in v4l2-dev.c. This prevents more fine-grained locking since at that level we cannot examine the ioctl arguments, we can only do that after video_usercopy is called. So push the locking down to __video_do_ioctl() and subdev_do_ioctl_lock(). This also allows us to make a few functions in v4l2-ioctl.c static and video_usercopy() is no longer exported. The locking scheme is not changed by this patch, just pushed down. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 6 ------ drivers/media/v4l2-core/v4l2-ioctl.c | 20 +++++++++++++++++--- drivers/media/v4l2-core/v4l2-subdev.c | 17 ++++++++++++++++- include/media/v4l2-dev.h | 9 --------- include/media/v4l2-ioctl.h | 12 ------------ 5 files changed, 33 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index c4f4357e9ca4..4ffd7d60a901 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -360,14 +360,8 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int ret = -ENODEV; if (vdev->fops->unlocked_ioctl) { - struct mutex *lock = v4l2_ioctl_get_lock(vdev, cmd); - - if (lock && mutex_lock_interruptible(lock)) - return -ERESTARTSYS; if (video_is_registered(vdev)) ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); - if (lock) - mutex_unlock(lock); } else ret = -ENOTTY; diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index c23fbfe90a9e..965fd301f617 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2655,14 +2655,15 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) -bool v4l2_is_known_ioctl(unsigned int cmd) +static bool v4l2_is_known_ioctl(unsigned int cmd) { if (_IOC_NR(cmd) >= V4L2_IOCTLS) return false; return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; } -struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd) +static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, + unsigned int cmd) { if (_IOC_NR(cmd) >= V4L2_IOCTLS) return vdev->lock; @@ -2713,6 +2714,7 @@ static long __video_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vfd = video_devdata(file); + struct mutex *lock; /* ioctl serialization mutex */ const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; bool write_only = false; struct v4l2_ioctl_info default_info; @@ -2731,6 +2733,16 @@ static long __video_do_ioctl(struct file *file, if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) vfh = file->private_data; + lock = v4l2_ioctl_get_lock(vfd, cmd); + + if (lock && mutex_lock_interruptible(lock)) + return -ERESTARTSYS; + + if (!video_is_registered(vfd)) { + ret = -ENODEV; + goto unlock; + } + if (v4l2_is_known_ioctl(cmd)) { info = &v4l2_ioctls[_IOC_NR(cmd)]; @@ -2780,6 +2792,9 @@ done: } } +unlock: + if (lock) + mutex_unlock(lock); return ret; } @@ -2969,7 +2984,6 @@ out: kvfree(mbuf); return err; } -EXPORT_SYMBOL(video_usercopy); long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index f9eed938d348..6a7f7f75dfd7 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -502,10 +502,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } +static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg) +{ + struct video_device *vdev = video_devdata(file); + struct mutex *lock = vdev->lock; + long ret = -ENODEV; + + if (lock && mutex_lock_interruptible(lock)) + return -ERESTARTSYS; + if (video_is_registered(vdev)) + ret = subdev_do_ioctl(file, cmd, arg); + if (lock) + mutex_unlock(lock); + return ret; +} + static long subdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return video_usercopy(file, cmd, arg, subdev_do_ioctl); + return video_usercopy(file, cmd, arg, subdev_do_ioctl_lock); } #ifdef CONFIG_COMPAT diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 30423aefe7c5..456ac13eca1d 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -435,15 +435,6 @@ void video_device_release(struct video_device *vdev); */ void video_device_release_empty(struct video_device *vdev); -/** - * v4l2_is_known_ioctl - Checks if a given cmd is a known V4L ioctl - * - * @cmd: ioctl command - * - * returns true if cmd is a known V4L2 ioctl - */ -bool v4l2_is_known_ioctl(unsigned int cmd); - /** * v4l2_disable_ioctl- mark that a given command isn't implemented. * shouldn't use core locking diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index a7b3f7c75d62..a8dbf5b54b5c 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -658,18 +658,6 @@ void v4l_printk_ioctl(const char *prefix, unsigned int cmd); struct video_device; - -/** - * v4l2_ioctl_get_lock - get the mutex (if any) that it is need to lock for - * a given command. - * - * @vdev: Pointer to struct &video_device. - * @cmd: Ioctl name. - * - * .. note:: Internal use only. Should not be used outside V4L2 core. - */ -struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned int cmd); - /* names for fancy debug output */ extern const char *v4l2_field_names[]; extern const char *v4l2_type_names[]; -- cgit v1.2.3-71-gd317