summaryrefslogtreecommitdiff
path: root/drivers/media/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 04:30:10 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 04:30:10 +0300
commitb1bc554e009e3aeed7e4cfd2e717c7a34a98c683 (patch)
treedb092dd7887e732588250f2c2f932e1bfc3f87a2 /drivers/media/pci
parent0ffb8a4c96e55ecf0e572aec1a0220af3da84e22 (diff)
parent68a72104cbcf38ad16500216e213fa4eb21c4be2 (diff)
downloadlinux-b1bc554e009e3aeed7e4cfd2e717c7a34a98c683.tar.xz
Merge tag 'media/v6.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - New sensor drivers: gc05a2, gc08a3 and imx283 - New serializer/deserializer drivers: max96714 and max96717 - New JPEG encoder driver: e5010 - Support for Raspberry Pi PiSP Backend (BE) ISP driver - Old documentation for av7110 driver removed, as a new version was added as Documentation/userspace-api/media/dvb/legacy*.rst - atompisp: Linux firmwares are now available, so drop firmware-related task from TODO and update firmware logic - The imx258 driver has gained several improvements - wave5 driver has gained support for HEVC decoding - em28xx gained support for MyGica UTV3 - av7110 budget-patch driver removed - Lots of other cleanups, improvements and fixes * tag 'media/v6.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (301 commits) media: raspberrypi: Switch to remove_new media: uapi: pisp_be_config: Add extra config fields media: uapi: pisp_be_config: Re-sort pisp_be_tiles_config media: uapi: pisp_common: Capitalize all macros media: uapi: pisp_common: Add 32 bpp format test media: uapi: pisp_be_config: Drop BIT() from uAPI media: stm32: dcmipp: correct error handling in dcmipp_create_subdevs media: atomisp: Fix spelling mistakes in sh_css_sp.c media: atomisp: Fix spelling mistake in ia_css_debug.c media: atomisp: Fix spelling mistake in hmm_bo.c media: atomisp: Fix spelling mistake in ia_css_eed1_8.host.c media: atomisp: Fix spelling mistake in sh_css_internal.h media: atomisp: Fix spelling mistake "pipline" -> "pipeline" media: atomisp: Remove unused GPIO related defines and APIs media: atomisp: Replace COMPILATION_ERROR_IF() by static_assert() media: atomisp: Clean up unused macros from math_support.h media: atomisp: csi2-bridge: Add DMI quirk for OV5693 on Xiaomi Mipad2 media: atomisp: Update TODO media: atomisp: Prefix firmware paths with "intel/ipu/" media: atomisp: Remove firmware_name module parameter ...
Diffstat (limited to 'drivers/media/pci')
-rw-r--r--drivers/media/pci/bt8xx/bt878.c9
-rw-r--r--drivers/media/pci/bt8xx/bt878.h3
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.c8
-rw-r--r--drivers/media/pci/cx18/cx18-scb.h2
-rw-r--r--drivers/media/pci/ddbridge/ddbridge.h2
-rw-r--r--drivers/media/pci/intel/ipu-bridge.c40
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-buttress.c4
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c98
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-queue.c3
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-video.c43
-rw-r--r--drivers/media/pci/intel/ivsc/mei_csi.c24
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c93
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.c66
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.c8
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c7
-rw-r--r--drivers/media/pci/mantis/hopper_cards.c2
-rw-r--r--drivers/media/pci/mantis/mantis_cards.c2
-rw-r--r--drivers/media/pci/mantis/mantis_common.h2
-rw-r--r--drivers/media/pci/mantis/mantis_dma.c4
-rw-r--r--drivers/media/pci/mantis/mantis_dma.h2
-rw-r--r--drivers/media/pci/mantis/mantis_dvb.c12
-rw-r--r--drivers/media/pci/ngene/ngene-core.c22
-rw-r--r--drivers/media/pci/ngene/ngene.h5
-rw-r--r--drivers/media/pci/saa7134/saa7134-alsa.c1
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c9
-rw-r--r--drivers/media/pci/saa7134/saa7134-empress.c1
-rw-r--r--drivers/media/pci/saa7134/saa7134-go7007.c1
-rw-r--r--drivers/media/pci/smipcie/smipcie-main.c18
-rw-r--r--drivers/media/pci/smipcie/smipcie.h3
-rw-r--r--drivers/media/pci/ttpci/budget-av.c3
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c27
-rw-r--r--drivers/media/pci/ttpci/budget-core.c11
-rw-r--r--drivers/media/pci/ttpci/budget.h5
-rw-r--r--drivers/media/pci/tw5864/tw5864-core.c2
-rw-r--r--drivers/media/pci/tw5864/tw5864-video.c13
-rw-r--r--drivers/media/pci/tw5864/tw5864.h7
38 files changed, 273 insertions, 297 deletions
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
index 90972d6952f1..62a6c4a80bed 100644
--- a/drivers/media/pci/bt8xx/bt878.c
+++ b/drivers/media/pci/bt8xx/bt878.c
@@ -300,8 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
}
if (astat & BT878_ARISCI) {
bt->finished_block = (stat & BT878_ARISCS) >> 28;
- if (bt->tasklet.callback)
- tasklet_schedule(&bt->tasklet);
+ if (bt->bh_work.func)
+ queue_work(system_bh_wq, &bt->bh_work);
break;
}
count++;
@@ -478,8 +478,8 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
btwrite(0, BT878_AINT_MASK);
bt878_num++;
- if (!bt->tasklet.func)
- tasklet_disable(&bt->tasklet);
+ if (!bt->bh_work.func)
+ disable_work_sync(&bt->bh_work);
return 0;
@@ -563,4 +563,5 @@ static void __exit bt878_cleanup_module(void)
module_init(bt878_init_module);
module_exit(bt878_cleanup_module);
+MODULE_DESCRIPTION("DVB/ATSC Support for bt878 based TV cards");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/bt8xx/bt878.h b/drivers/media/pci/bt8xx/bt878.h
index fde8db293c54..5b1c7f56e553 100644
--- a/drivers/media/pci/bt8xx/bt878.h
+++ b/drivers/media/pci/bt8xx/bt878.h
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+#include <linux/workqueue.h>
#include "bt848.h"
#include "bttv.h"
@@ -120,7 +121,7 @@ struct bt878 {
dma_addr_t risc_dma;
u32 risc_pos;
- struct tasklet_struct tasklet;
+ struct work_struct bh_work;
int shutdown;
};
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
index 390cbba6c065..f0fbb468aea2 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
@@ -39,9 +39,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
-static void dvb_bt8xx_task(struct tasklet_struct *t)
+static void dvb_bt8xx_work(struct work_struct *t)
{
- struct bt878 *bt = from_tasklet(bt, t, tasklet);
+ struct bt878 *bt = from_work(bt, t, bh_work);
struct dvb_bt8xx_card *card = dev_get_drvdata(&bt->adapter->dev);
dprintk("%d\n", card->bt->finished_block);
@@ -782,7 +782,7 @@ static int dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
goto err_disconnect_frontend;
}
- tasklet_setup(&card->bt->tasklet, dvb_bt8xx_task);
+ INIT_WORK(&card->bt->bh_work, dvb_bt8xx_work);
frontend_init(card, type);
@@ -922,7 +922,7 @@ static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
bt878_stop(card->bt);
- tasklet_kill(&card->bt->tasklet);
+ cancel_work_sync(&card->bt->bh_work);
dvb_net_release(&card->dvbnet);
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
diff --git a/drivers/media/pci/cx18/cx18-scb.h b/drivers/media/pci/cx18/cx18-scb.h
index f7105421dd25..841edc0712ab 100644
--- a/drivers/media/pci/cx18/cx18-scb.h
+++ b/drivers/media/pci/cx18/cx18-scb.h
@@ -258,7 +258,7 @@ struct cx18_scb {
struct cx18_mailbox ppu2epu_mb;
struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
- struct cx18_mdl_ent cpu_mdl[1];
+ struct cx18_mdl_ent cpu_mdl[];
};
void cx18_init_scb(struct cx18 *cx);
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index f3699dbd193f..f01ecdb0b627 100644
--- a/drivers/media/pci/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
@@ -298,7 +298,7 @@ struct ddb_link {
spinlock_t lock; /* lock link access */
struct mutex flash_mutex; /* lock flash access */
struct ddb_lnb lnb;
- struct tasklet_struct tasklet;
+ struct work_struct bh_work;
struct ddb_ids ids;
spinlock_t temp_lock; /* lock temp chip access */
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index 61750cc98d70..a0e9a71580b5 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -43,28 +43,46 @@
* becoming apparent in the future.
*
* Do not add an entry for a sensor that is not actually supported.
+ *
+ * Please keep the list sorted by ACPI HID.
*/
static const struct ipu_sensor_config ipu_supported_sensors[] = {
+ /* Himax HM11B1 */
+ IPU_SENSOR_CONFIG("HIMX11B1", 1, 384000000),
+ /* Himax HM2170 */
+ IPU_SENSOR_CONFIG("HIMX2170", 1, 384000000),
+ /* Himax HM2172 */
+ IPU_SENSOR_CONFIG("HIMX2172", 1, 384000000),
+ /* GalaxyCore GC0310 */
+ IPU_SENSOR_CONFIG("INT0310", 0),
/* Omnivision OV5693 */
IPU_SENSOR_CONFIG("INT33BE", 1, 419200000),
+ /* Omnivision OV2740 */
+ IPU_SENSOR_CONFIG("INT3474", 1, 180000000),
/* Omnivision OV8865 */
IPU_SENSOR_CONFIG("INT347A", 1, 360000000),
/* Omnivision OV7251 */
IPU_SENSOR_CONFIG("INT347E", 1, 319200000),
+ /* Hynix Hi-556 */
+ IPU_SENSOR_CONFIG("INT3537", 1, 437000000),
+ /* Omnivision OV01A10 / OV01A1S */
+ IPU_SENSOR_CONFIG("OVTI01A0", 1, 400000000),
+ IPU_SENSOR_CONFIG("OVTI01AS", 1, 400000000),
+ /* Omnivision OV02C10 */
+ IPU_SENSOR_CONFIG("OVTI02C1", 1, 400000000),
+ /* Omnivision OV02E10 */
+ IPU_SENSOR_CONFIG("OVTI02E1", 1, 360000000),
+ /* Omnivision OV08A10 */
+ IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000),
+ /* Omnivision OV08x40 */
+ IPU_SENSOR_CONFIG("OVTI08F4", 1, 400000000),
+ /* Omnivision OV13B10 */
+ IPU_SENSOR_CONFIG("OVTI13B1", 1, 560000000),
+ IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
/* Omnivision OV2680 */
IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000),
- /* Omnivision ov8856 */
+ /* Omnivision OV8856 */
IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
- /* Omnivision ov2740 */
- IPU_SENSOR_CONFIG("INT3474", 1, 180000000),
- /* Hynix hi556 */
- IPU_SENSOR_CONFIG("INT3537", 1, 437000000),
- /* Omnivision ov13b10 */
- IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
- /* GalaxyCore GC0310 */
- IPU_SENSOR_CONFIG("INT0310", 0),
- /* Omnivision ov01a10 */
- IPU_SENSOR_CONFIG("OVTI01A0", 1, 400000000),
};
static const struct ipu_property_names prop_names = {
diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
index 23c537e7ce1e..e47f84c30e10 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
@@ -163,8 +163,8 @@ int ipu6_buttress_ipc_reset(struct ipu6_device *isp,
writel(ENTRY, isp->base + ipc->csr_out);
break;
default:
- dev_warn_ratelimited(&isp->pdev->dev,
- "Unexpected CSR 0x%x\n", val);
+ dev_dbg_ratelimited(&isp->pdev->dev,
+ "Unexpected CSR 0x%x\n", val);
break;
}
} while (retries--);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
index b9ce4324996d..051898ce53f4 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
@@ -345,42 +345,61 @@ static int ipu6_isys_csi2_set_stream(struct v4l2_subdev *sd,
return ret;
}
-static int set_stream(struct v4l2_subdev *sd, int enable)
+static int ipu6_isys_csi2_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
{
struct ipu6_isys_subdev *asd = to_ipu6_isys_subdev(sd);
struct ipu6_isys_csi2 *csi2 = to_ipu6_isys_csi2(asd);
- struct device *dev = &csi2->isys->adev->auxdev.dev;
struct ipu6_isys_csi2_timing timing = { };
- unsigned int nlanes;
+ struct v4l2_subdev *remote_sd;
+ struct media_pad *remote_pad;
+ u64 sink_streams;
int ret;
- dev_dbg(dev, "csi2 stream %s callback\n", enable ? "on" : "off");
-
- if (!enable) {
- csi2->stream_count--;
- if (csi2->stream_count)
- return 0;
-
- ipu6_isys_csi2_set_stream(sd, &timing, 0, enable);
- return 0;
- }
-
- if (csi2->stream_count) {
- csi2->stream_count++;
- return 0;
- }
+ remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+ remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
- nlanes = csi2->nlanes;
+ sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
+ CSI2_PAD_SINK,
+ &streams_mask);
ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);
if (ret)
return ret;
- ret = ipu6_isys_csi2_set_stream(sd, &timing, nlanes, enable);
+ ret = ipu6_isys_csi2_set_stream(sd, &timing, csi2->nlanes, true);
if (ret)
return ret;
- csi2->stream_count++;
+ ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index,
+ sink_streams);
+ if (ret) {
+ ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ipu6_isys_csi2_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct v4l2_subdev *remote_sd;
+ struct media_pad *remote_pad;
+ u64 sink_streams;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
+ CSI2_PAD_SINK,
+ &streams_mask);
+
+ remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+ remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+ ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+
+ v4l2_subdev_disable_streams(remote_sd, remote_pad->index, sink_streams);
return 0;
}
@@ -475,10 +494,6 @@ static int ipu6_isys_csi2_get_sel(struct v4l2_subdev *sd,
return ret;
}
-static const struct v4l2_subdev_video_ops csi2_sd_video_ops = {
- .s_stream = set_stream,
-};
-
static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = {
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ipu6_isys_subdev_set_fmt,
@@ -486,11 +501,12 @@ static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = {
.set_selection = ipu6_isys_csi2_set_sel,
.enum_mbus_code = ipu6_isys_subdev_enum_mbus_code,
.set_routing = ipu6_isys_subdev_set_routing,
+ .enable_streams = ipu6_isys_csi2_enable_streams,
+ .disable_streams = ipu6_isys_csi2_disable_streams,
};
static const struct v4l2_subdev_ops csi2_sd_ops = {
.core = &csi2_sd_core_ops,
- .video = &csi2_sd_video_ops,
.pad = &csi2_sd_pad_ops,
};
@@ -631,33 +647,3 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
return 0;
}
-
-void ipu6_isys_set_csi2_streams_status(struct ipu6_isys_video *av, bool status)
-{
- struct ipu6_isys_stream *stream = av->stream;
- struct v4l2_subdev *sd = &stream->asd->sd;
- struct v4l2_subdev_state *state;
- struct media_pad *r_pad;
- unsigned int i;
- u32 r_stream;
-
- r_pad = media_pad_remote_pad_first(&av->pad);
- r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, r_pad->index);
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
-
- for (i = 0; i < state->stream_configs.num_configs; i++) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
-
- if (cfg->pad == r_pad->index && r_stream == cfg->stream) {
- dev_dbg(&av->isys->adev->auxdev.dev,
- "%s: pad:%u, stream:%u, status:%u\n",
- sd->entity.name, r_pad->index, r_stream,
- status);
- cfg->enabled = status;
- }
- }
-
- v4l2_subdev_unlock_state(state);
-}
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
index eba6b29386ea..bc8594c94f99 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
@@ -45,7 +45,6 @@ struct ipu6_isys_csi2 {
u32 receiver_errors;
unsigned int nlanes;
unsigned int port;
- unsigned int stream_count;
};
struct ipu6_isys_csi2_timing {
@@ -77,6 +76,5 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
struct ipu6_isys_csi2 *csi2,
struct media_entity *source_entity,
struct v4l2_mbus_frame_desc_entry *entry);
-void ipu6_isys_set_csi2_streams_status(struct ipu6_isys_video *av, bool status);
#endif /* IPU6_ISYS_CSI2_H */
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
index 4bd4e324abc9..03dbb0e0ea79 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
@@ -551,7 +551,6 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
stream->nr_queues);
list_add(&aq->node, &stream->queues);
- ipu6_isys_set_csi2_streams_status(av, true);
ipu6_isys_configure_stream_watermark(av, true);
ipu6_isys_update_stream_watermark(av, true);
@@ -598,8 +597,6 @@ static void stop_streaming(struct vb2_queue *q)
struct ipu6_isys_video *av = ipu6_isys_queue_to_video(aq);
struct ipu6_isys_stream *stream = av->stream;
- ipu6_isys_set_csi2_streams_status(av, false);
-
mutex_lock(&stream->mutex);
ipu6_isys_update_stream_watermark(av, false);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index 06090cc0a476..b37561352ead 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -990,9 +990,7 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
struct v4l2_subdev_state *subdev_state;
struct device *dev = &av->isys->adev->auxdev.dev;
struct v4l2_subdev *sd;
- struct v4l2_subdev *ssd;
struct media_pad *r_pad;
- struct media_pad *s_pad;
u32 sink_pad, sink_stream;
u64 r_stream;
u64 stream_mask = 0;
@@ -1003,7 +1001,6 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
if (WARN(!stream->source_entity, "No source entity for stream\n"))
return -ENODEV;
- ssd = media_entity_to_v4l2_subdev(stream->source_entity);
sd = &stream->asd->sd;
r_pad = media_pad_remote_pad_first(&av->pad);
r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, r_pad->index);
@@ -1017,27 +1014,15 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
if (ret)
return ret;
- s_pad = media_pad_remote_pad_first(&stream->asd->pad[sink_pad]);
-
stream_mask = get_stream_mask_by_pipeline(av);
if (!state) {
stop_streaming_firmware(av);
- /* stop external sub-device now. */
- dev_dbg(dev, "disable streams 0x%llx of %s\n", stream_mask,
- ssd->name);
- ret = v4l2_subdev_disable_streams(ssd, s_pad->index,
- stream_mask);
- if (ret) {
- dev_err(dev, "disable streams of %s failed with %d\n",
- ssd->name, ret);
- return ret;
- }
-
/* stop sub-device which connects with video */
- dev_dbg(dev, "stream off entity %s pad:%d\n", sd->name,
- r_pad->index);
- ret = v4l2_subdev_call(sd, video, s_stream, state);
+ dev_dbg(dev, "stream off entity %s pad:%d mask:0x%llx\n",
+ sd->name, r_pad->index, stream_mask);
+ ret = v4l2_subdev_disable_streams(sd, r_pad->index,
+ stream_mask);
if (ret) {
dev_err(dev, "stream off %s failed with %d\n", sd->name,
ret);
@@ -1052,34 +1037,20 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
}
/* start sub-device which connects with video */
- dev_dbg(dev, "stream on %s pad %d\n", sd->name, r_pad->index);
- ret = v4l2_subdev_call(sd, video, s_stream, state);
+ dev_dbg(dev, "stream on %s pad %d mask 0x%llx\n", sd->name,
+ r_pad->index, stream_mask);
+ ret = v4l2_subdev_enable_streams(sd, r_pad->index, stream_mask);
if (ret) {
dev_err(dev, "stream on %s failed with %d\n", sd->name,
ret);
goto out_media_entity_stop_streaming_firmware;
}
-
- /* start external sub-device now. */
- dev_dbg(dev, "enable streams 0x%llx of %s\n", stream_mask,
- ssd->name);
- ret = v4l2_subdev_enable_streams(ssd, s_pad->index,
- stream_mask);
- if (ret) {
- dev_err(dev,
- "enable streams 0x%llx of %s failed with %d\n",
- stream_mask, stream->source_entity->name, ret);
- goto out_media_entity_stop_streaming;
- }
}
av->streaming = state;
return 0;
-out_media_entity_stop_streaming:
- v4l2_subdev_disable_streams(sd, r_pad->index, BIT(r_stream));
-
out_media_entity_stop_streaming_firmware:
stop_streaming_firmware(av);
diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c
index f04a89584334..2a9c12c975ca 100644
--- a/drivers/media/pci/intel/ivsc/mei_csi.c
+++ b/drivers/media/pci/intel/ivsc/mei_csi.c
@@ -126,6 +126,8 @@ struct mei_csi {
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *freq_ctrl;
struct v4l2_ctrl *privacy_ctrl;
+ /* lock for v4l2 controls */
+ struct mutex ctrl_lock;
unsigned int remote_pad;
/* start streaming or not */
int streaming;
@@ -136,9 +138,6 @@ struct mei_csi {
u32 nr_of_lanes;
/* frequency of the CSI-2 link */
u64 link_freq;
-
- /* privacy status */
- enum ivsc_privacy_status status;
};
static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
@@ -190,7 +189,11 @@ static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len)
/* command response status */
ret = csi->cmd_response.status;
- if (ret) {
+ if (ret == -1) {
+ /* notify privacy on instead of reporting error */
+ ret = 0;
+ v4l2_ctrl_s_ctrl(csi->privacy_ctrl, 1);
+ } else if (ret) {
ret = -EINVAL;
goto out;
}
@@ -265,10 +268,9 @@ static void mei_csi_rx(struct mei_cl_device *cldev)
switch (notif.cmd_id) {
case CSI_PRIVACY_NOTIF:
- if (notif.cont.cont < CSI_PRIVACY_MAX) {
- csi->status = notif.cont.cont;
- v4l2_ctrl_s_ctrl(csi->privacy_ctrl, csi->status);
- }
+ if (notif.cont.cont < CSI_PRIVACY_MAX)
+ v4l2_ctrl_s_ctrl(csi->privacy_ctrl,
+ notif.cont.cont == CSI_PRIVACY_ON);
break;
case CSI_SET_OWNER:
case CSI_SET_CONF:
@@ -559,11 +561,13 @@ static int mei_csi_init_controls(struct mei_csi *csi)
u32 max;
int ret;
+ mutex_init(&csi->ctrl_lock);
+
ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2);
if (ret)
return ret;
- csi->ctrl_handler.lock = &csi->lock;
+ csi->ctrl_handler.lock = &csi->ctrl_lock;
max = ARRAY_SIZE(link_freq_menu_items) - 1;
csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler,
@@ -755,6 +759,7 @@ err_entity:
err_ctrl_handler:
v4l2_ctrl_handler_free(&csi->ctrl_handler);
+ mutex_destroy(&csi->ctrl_lock);
v4l2_async_nf_unregister(&csi->notifier);
v4l2_async_nf_cleanup(&csi->notifier);
@@ -774,6 +779,7 @@ static void mei_csi_remove(struct mei_cl_device *cldev)
v4l2_async_nf_unregister(&csi->notifier);
v4l2_async_nf_cleanup(&csi->notifier);
v4l2_ctrl_handler_free(&csi->ctrl_handler);
+ mutex_destroy(&csi->ctrl_lock);
v4l2_async_unregister_subdev(&csi->subdev);
v4l2_subdev_cleanup(&csi->subdev);
media_entity_cleanup(&csi->subdev.entity);
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index ba503d820e48..ecc20cd89926 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -371,33 +371,6 @@ int ivtv_msleep_timeout(unsigned int msecs, int intr)
return 0;
}
-/* Release ioremapped memory */
-static void ivtv_iounmap(struct ivtv *itv)
-{
- if (itv == NULL)
- return;
-
- /* Release registers memory */
- if (itv->reg_mem != NULL) {
- IVTV_DEBUG_INFO("releasing reg_mem\n");
- iounmap(itv->reg_mem);
- itv->reg_mem = NULL;
- }
- /* Release io memory */
- if (itv->has_cx23415 && itv->dec_mem != NULL) {
- IVTV_DEBUG_INFO("releasing dec_mem\n");
- iounmap(itv->dec_mem);
- }
- itv->dec_mem = NULL;
-
- /* Release io memory */
- if (itv->enc_mem != NULL) {
- IVTV_DEBUG_INFO("releasing enc_mem\n");
- iounmap(itv->enc_mem);
- itv->enc_mem = NULL;
- }
-}
-
/* Hauppauge card? get values from tveeprom */
void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
{
@@ -833,7 +806,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
IVTV_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(pdev)) {
+ if (pcim_enable_device(pdev)) {
IVTV_ERR("Can't enable device!\n");
return -EIO;
}
@@ -841,24 +814,24 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
IVTV_ERR("No suitable DMA available.\n");
return -EIO;
}
- if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
+ if (!devm_request_mem_region(&pdev->dev, itv->base_addr,
+ IVTV_ENCODER_SIZE, "ivtv encoder")) {
IVTV_ERR("Cannot request encoder memory region.\n");
return -EIO;
}
- if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
- IVTV_REG_SIZE, "ivtv registers")) {
+ if (!devm_request_mem_region(&pdev->dev,
+ itv->base_addr + IVTV_REG_OFFSET,
+ IVTV_REG_SIZE, "ivtv registers")) {
IVTV_ERR("Cannot request register memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
return -EIO;
}
if (itv->has_cx23415 &&
- !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE, "ivtv decoder")) {
+ !devm_request_mem_region(&pdev->dev,
+ itv->base_addr + IVTV_DECODER_OFFSET,
+ IVTV_DECODER_SIZE, "ivtv decoder")) {
IVTV_ERR("Cannot request decoder memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
return -EIO;
}
@@ -870,11 +843,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_ERR("Bus Mastering is not enabled\n");
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
return -ENXIO;
}
}
@@ -1033,37 +1001,37 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
/* PCI Device Setup */
retval = ivtv_setup_pci(itv, pdev, pci_id);
- if (retval == -EIO)
+ if (retval == -EIO || retval == -ENXIO)
goto free_worker;
- if (retval == -ENXIO)
- goto free_mem;
/* map io memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE);
- itv->enc_mem = ioremap(itv->base_addr + IVTV_ENCODER_OFFSET,
- IVTV_ENCODER_SIZE);
+ itv->enc_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_ENCODER_OFFSET,
+ IVTV_ENCODER_SIZE);
if (!itv->enc_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 encoder memory\n");
IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_mem;
+ goto free_worker;
}
if (itv->has_cx23415) {
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- itv->dec_mem = ioremap(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
+ itv->dec_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_DECODER_OFFSET,
+ IVTV_DECODER_SIZE);
if (!itv->dec_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415 decoder memory\n");
IVTV_ERR("Each capture card with a CX23415 needs 8 MB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_mem;
+ goto free_worker;
}
}
else {
@@ -1073,26 +1041,27 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
/* map registers memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- itv->reg_mem =
- ioremap(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
+ itv->reg_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_REG_OFFSET,
+ IVTV_REG_SIZE);
if (!itv->reg_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 register space\n");
IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_io;
+ goto free_worker;
}
retval = ivtv_gpio_init(itv);
if (retval)
- goto free_io;
+ goto free_worker;
/* active i2c */
IVTV_DEBUG_INFO("activating i2c...\n");
if (init_ivtv_i2c(itv)) {
IVTV_ERR("Could not initialize i2c\n");
- goto free_io;
+ goto free_worker;
}
if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
@@ -1277,13 +1246,6 @@ free_irq:
free_i2c:
v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
exit_ivtv_i2c(itv);
-free_io:
- ivtv_iounmap(itv);
-free_mem:
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
free_worker:
kthread_stop(itv->irq_worker_task);
err:
@@ -1439,14 +1401,7 @@ static void ivtv_remove(struct pci_dev *pdev)
exit_ivtv_i2c(itv);
free_irq(itv->pdev->irq, (void *)itv);
- ivtv_iounmap(itv);
-
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- pci_disable_device(itv->pdev);
for (i = 0; i < IVTV_VBI_FRAMES; i++)
kfree(itv->vbi.sliced_mpeg_data[i]);
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c
index 4202c3a47d33..cfa28d035586 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -21,6 +21,7 @@
#include "ivtv-ioctl.h"
#include "ivtv-cards.h"
#include "ivtv-firmware.h"
+#include <linux/lockdep.h>
#include <media/v4l2-event.h>
#include <media/i2c/saa7115.h>
@@ -190,12 +191,27 @@ static void ivtv_update_pgm_info(struct ivtv *itv)
itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
}
+static void ivtv_schedule(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+ DEFINE_WAIT(wait);
+
+ lockdep_assert_held(&itv->serialize_lock);
+
+ mutex_unlock(&itv->serialize_lock);
+ prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
+ /* New buffers might have become free before we were added to the waitqueue */
+ if (!s->q_free.buffers)
+ schedule();
+ finish_wait(&s->waitq, &wait);
+ mutex_lock(&itv->serialize_lock);
+}
+
static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
{
struct ivtv *itv = s->itv;
struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
struct ivtv_buffer *buf;
- DEFINE_WAIT(wait);
*err = 0;
while (1) {
@@ -258,13 +274,7 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
}
/* wait for more data to arrive */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added to the waitqueue */
- if (!s->q_full.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
+ ivtv_schedule(s);
if (signal_pending(current)) {
/* return if a signal was received */
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
@@ -533,6 +543,25 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
return 0;
}
+static int ivtv_schedule_dma(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+ int got_sig;
+ DEFINE_WAIT(wait);
+
+ lockdep_assert_held(&itv->serialize_lock);
+
+ mutex_unlock(&itv->serialize_lock);
+ prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
+ while (!(got_sig = signal_pending(current)) &&
+ test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
+ schedule();
+ finish_wait(&itv->dma_waitq, &wait);
+ mutex_lock(&itv->serialize_lock);
+
+ return got_sig;
+}
+
static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
{
struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -544,7 +573,6 @@ static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t
int bytes_written = 0;
int mode;
int rc;
- DEFINE_WAIT(wait);
IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
@@ -618,13 +646,7 @@ retry:
break;
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become free before we were added to the waitqueue */
- if (!s->q_free.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
+ ivtv_schedule(s);
if (signal_pending(current)) {
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
return -EINTR;
@@ -674,20 +696,10 @@ retry:
if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
if (s->q_full.length >= itv->dma_data_req_size) {
- int got_sig;
-
if (mode == OUT_YUV)
ivtv_yuv_setup_stream_frame(itv);
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (!(got_sig = signal_pending(current)) &&
- test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig) {
+ if (ivtv_schedule_dma(s)) {
IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
return -EINTR;
}
diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
index 99b9f55ca829..f467a00492f4 100644
--- a/drivers/media/pci/ivtv/ivtv-udma.c
+++ b/drivers/media/pci/ivtv/ivtv-udma.c
@@ -131,6 +131,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
/* Fill SG List with new values */
if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
+ IVTV_DEBUG_WARN("%s: could not allocate bounce buffers for highmem userspace buffers\n",
+ __func__);
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0;
return -ENOMEM;
@@ -139,6 +141,12 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
/* Map SG List */
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE);
+ if (!dma->SG_length) {
+ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+ unpin_user_pages(dma->map, dma->page_count);
+ dma->page_count = 0;
+ return -EINVAL;
+ }
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index 582146f8d70d..2d9274537725 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -114,6 +114,12 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
}
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE);
+ if (!dma->SG_length) {
+ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+ unpin_user_pages(dma->map, dma->page_count);
+ dma->page_count = 0;
+ return -EINVAL;
+ }
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 410477e3e621..90c584cf97c2 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -104,6 +104,7 @@ MODULE_PARM_DESC(osd_xres,
"\t\t\tdefault 640");
MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
+MODULE_DESCRIPTION("Conexant cx23415 framebuffer support");
MODULE_LICENSE("GPL");
/* --------------------------------------------------------------------- */
@@ -281,10 +282,10 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
/* Map User DMA */
if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
mutex_unlock(&itv->udma.lock);
- IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with pin_user_pages: %d bytes, %d pages returned\n",
- size_in_bytes, itv->udma.page_count);
+ IVTVFB_WARN("%s, Error in ivtv_udma_setup: %d bytes, %d pages returned\n",
+ __func__, size_in_bytes, itv->udma.page_count);
- /* pin_user_pages must have failed completely */
+ /* pin_user_pages or DMA must have failed completely */
return -EIO;
}
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index c0bd5d7e148b..b85aef4e2b24 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -116,7 +116,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
if (stat & MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
- tasklet_schedule(&mantis->tasklet);
+ queue_work(system_bh_wq, &mantis->bh_work);
}
if (stat & MANTIS_INT_I2CDONE) {
dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 906e4500d87d..b44b4cf42f86 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -125,7 +125,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
if (stat & MANTIS_INT_RISCI) {
dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
- tasklet_schedule(&mantis->tasklet);
+ queue_work(system_bh_wq, &mantis->bh_work);
}
if (stat & MANTIS_INT_I2CDONE) {
dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
index d88ac280226c..6e563ecd94e8 100644
--- a/drivers/media/pci/mantis/mantis_common.h
+++ b/drivers/media/pci/mantis/mantis_common.h
@@ -125,7 +125,7 @@ struct mantis_pci {
__le32 *risc_cpu;
dma_addr_t risc_dma;
- struct tasklet_struct tasklet;
+ struct work_struct bh_work;
spinlock_t intmask_lock;
struct i2c_adapter adapter;
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
index 80c843936493..eeb210a2862f 100644
--- a/drivers/media/pci/mantis/mantis_dma.c
+++ b/drivers/media/pci/mantis/mantis_dma.c
@@ -200,9 +200,9 @@ void mantis_dma_stop(struct mantis_pci *mantis)
}
-void mantis_dma_xfer(struct tasklet_struct *t)
+void mantis_dma_xfer(struct work_struct *t)
{
- struct mantis_pci *mantis = from_tasklet(mantis, t, tasklet);
+ struct mantis_pci *mantis = from_work(mantis, t, bh_work);
struct mantis_hwconfig *config = mantis->hwconfig;
while (mantis->last_block != mantis->busy_block) {
diff --git a/drivers/media/pci/mantis/mantis_dma.h b/drivers/media/pci/mantis/mantis_dma.h
index 37da982c9c29..5db0d3728f15 100644
--- a/drivers/media/pci/mantis/mantis_dma.h
+++ b/drivers/media/pci/mantis/mantis_dma.h
@@ -13,6 +13,6 @@ extern int mantis_dma_init(struct mantis_pci *mantis);
extern int mantis_dma_exit(struct mantis_pci *mantis);
extern void mantis_dma_start(struct mantis_pci *mantis);
extern void mantis_dma_stop(struct mantis_pci *mantis);
-extern void mantis_dma_xfer(struct tasklet_struct *t);
+extern void mantis_dma_xfer(struct work_struct *t);
#endif /* __MANTIS_DMA_H */
diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c
index c7ba4a76e608..398e32f44692 100644
--- a/drivers/media/pci/mantis/mantis_dvb.c
+++ b/drivers/media/pci/mantis/mantis_dvb.c
@@ -105,7 +105,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
if (mantis->feeds == 1) {
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
mantis_dma_start(mantis);
- tasklet_enable(&mantis->tasklet);
+ enable_and_queue_work(system_bh_wq, &mantis->bh_work);
}
return mantis->feeds;
@@ -125,7 +125,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
mantis->feeds--;
if (mantis->feeds == 0) {
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
- tasklet_disable(&mantis->tasklet);
+ disable_work_sync(&mantis->bh_work);
mantis_dma_stop(mantis);
}
@@ -205,8 +205,8 @@ int mantis_dvb_init(struct mantis_pci *mantis)
}
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
- tasklet_setup(&mantis->tasklet, mantis_dma_xfer);
- tasklet_disable(&mantis->tasklet);
+ INIT_WORK(&mantis->bh_work, mantis_dma_xfer);
+ disable_work_sync(&mantis->bh_work);
if (mantis->hwconfig) {
result = config->frontend_init(mantis, mantis->fe);
if (result < 0) {
@@ -235,7 +235,7 @@ int mantis_dvb_init(struct mantis_pci *mantis)
/* Error conditions .. */
err5:
- tasklet_kill(&mantis->tasklet);
+ cancel_work_sync(&mantis->bh_work);
dvb_net_release(&mantis->dvbnet);
if (mantis->fe) {
dvb_unregister_frontend(mantis->fe);
@@ -273,7 +273,7 @@ int mantis_dvb_exit(struct mantis_pci *mantis)
dvb_frontend_detach(mantis->fe);
}
- tasklet_kill(&mantis->tasklet);
+ cancel_work_sync(&mantis->bh_work);
dvb_net_release(&mantis->dvbnet);
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index 24ec576dc3bf..db6796240bce 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -50,9 +50,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/* nGene interrupt handler **************************************************/
/****************************************************************************/
-static void event_tasklet(struct tasklet_struct *t)
+static void event_bh_work(struct work_struct *t)
{
- struct ngene *dev = from_tasklet(dev, t, event_tasklet);
+ struct ngene *dev = from_work(dev, t, event_bh_work);
while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) {
struct EVENT_BUFFER Event =
@@ -68,9 +68,9 @@ static void event_tasklet(struct tasklet_struct *t)
}
}
-static void demux_tasklet(struct tasklet_struct *t)
+static void demux_bh_work(struct work_struct *t)
{
- struct ngene_channel *chan = from_tasklet(chan, t, demux_tasklet);
+ struct ngene_channel *chan = from_work(chan, t, demux_bh_work);
struct device *pdev = &chan->dev->pci_dev->dev;
struct SBufferHeader *Cur = chan->nextBuffer;
@@ -204,7 +204,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
dev->EventQueueOverflowFlag = 1;
}
dev->EventBuffer->EventStatus &= ~0x80;
- tasklet_schedule(&dev->event_tasklet);
+ queue_work(system_bh_wq, &dev->event_bh_work);
rc = IRQ_HANDLED;
}
@@ -217,8 +217,8 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
ngeneBuffer.SR.Flags & 0xC0) == 0x80) {
dev->channel[i].nextBuffer->
ngeneBuffer.SR.Flags |= 0x40;
- tasklet_schedule(
- &dev->channel[i].demux_tasklet);
+ queue_work(system_bh_wq,
+ &dev->channel[i].demux_bh_work);
rc = IRQ_HANDLED;
}
}
@@ -1181,7 +1181,7 @@ static void ngene_init(struct ngene *dev)
struct device *pdev = &dev->pci_dev->dev;
int i;
- tasklet_setup(&dev->event_tasklet, event_tasklet);
+ INIT_WORK(&dev->event_bh_work, event_bh_work);
memset_io(dev->iomem + 0xc000, 0x00, 0x220);
memset_io(dev->iomem + 0xc400, 0x00, 0x100);
@@ -1395,7 +1395,7 @@ static void release_channel(struct ngene_channel *chan)
if (chan->running)
set_transfer(chan, 0);
- tasklet_kill(&chan->demux_tasklet);
+ cancel_work_sync(&chan->demux_bh_work);
if (chan->ci_dev) {
dvb_unregister_device(chan->ci_dev);
@@ -1445,7 +1445,7 @@ static int init_channel(struct ngene_channel *chan)
struct ngene_info *ni = dev->card_info;
int io = ni->io_type[nr];
- tasklet_setup(&chan->demux_tasklet, demux_tasklet);
+ INIT_WORK(&chan->demux_bh_work, demux_bh_work);
chan->users = 0;
chan->type = io;
chan->mode = chan->type; /* for now only one mode */
@@ -1649,7 +1649,7 @@ void ngene_remove(struct pci_dev *pdev)
struct ngene *dev = pci_get_drvdata(pdev);
int i;
- tasklet_kill(&dev->event_tasklet);
+ cancel_work_sync(&dev->event_bh_work);
for (i = MAX_STREAM - 1; i >= 0; i--)
release_channel(&dev->channel[i]);
if (dev->ci.en)
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index d1d7da84cd9d..9f989420b9e7 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -16,6 +16,7 @@
#include <linux/scatterlist.h>
#include <linux/dvb/frontend.h>
+#include <linux/workqueue.h>
#include <media/dmxdev.h>
#include <media/dvbdev.h>
@@ -621,7 +622,7 @@ struct ngene_channel {
int users;
struct video_device *v4l_dev;
struct dvb_device *ci_dev;
- struct tasklet_struct demux_tasklet;
+ struct work_struct demux_bh_work;
struct SBufferHeader *nextBuffer;
enum KSSTATE State;
@@ -717,7 +718,7 @@ struct ngene {
struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE];
int EventQueueOverflowCount;
int EventQueueOverflowFlag;
- struct tasklet_struct event_tasklet;
+ struct work_struct event_bh_work;
struct EVENT_BUFFER *EventBuffer;
int EventQueueWriteIndex;
int EventQueueReadIndex;
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c
index dd2236c5c4a1..f86a44dfe6e3 100644
--- a/drivers/media/pci/saa7134/saa7134-alsa.c
+++ b/drivers/media/pci/saa7134/saa7134-alsa.c
@@ -1254,5 +1254,6 @@ static void saa7134_alsa_exit(void)
/* We initialize this late, to make sure the sound system is up and running */
late_initcall(saa7134_alsa_init);
module_exit(saa7134_alsa_exit);
+MODULE_DESCRIPTION("Philips SAA7134 DMA audio support");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index 9c6cfef03331..6de8a02314af 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -52,6 +52,7 @@
#include "s5h1411.h"
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_DESCRIPTION("DVB/ATSC Support for saa7134 based TV cards");
MODULE_LICENSE("GPL");
static unsigned int antenna_pwr;
@@ -466,7 +467,9 @@ static int philips_europa_tuner_sleep(struct dvb_frontend *fe)
/* switch the board to analog mode */
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
+ if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1)
+ return -EIO;
+
return 0;
}
@@ -1018,7 +1021,9 @@ static int md8800_set_voltage2(struct dvb_frontend *fe,
else
wbuf[1] = rbuf & 0xef;
msg[0].len = 2;
- i2c_transfer(&dev->i2c_adap, msg, 1);
+ if (i2c_transfer(&dev->i2c_adap, msg, 1) != 1)
+ return -EIO;
+
return 0;
}
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 434fa1ee1c33..bbf480ab31ca 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -19,6 +19,7 @@
/* ------------------------------------------------------------------ */
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_DESCRIPTION("Philips SAA7134 empress support");
MODULE_LICENSE("GPL");
static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c
index da83893ffee9..bd37db5ce363 100644
--- a/drivers/media/pci/saa7134/saa7134-go7007.c
+++ b/drivers/media/pci/saa7134/saa7134-go7007.c
@@ -516,4 +516,5 @@ static void __exit saa7134_go7007_mod_cleanup(void)
module_init(saa7134_go7007_mod_init);
module_exit(saa7134_go7007_mod_cleanup);
+MODULE_DESCRIPTION("go7007 support for saa7134 based TV cards");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/pci/smipcie/smipcie-main.c b/drivers/media/pci/smipcie/smipcie-main.c
index 0c300d019d9c..7db6d443fc54 100644
--- a/drivers/media/pci/smipcie/smipcie-main.c
+++ b/drivers/media/pci/smipcie/smipcie-main.c
@@ -279,10 +279,10 @@ static void smi_port_clearInterrupt(struct smi_port *port)
(port->_dmaInterruptCH0 | port->_dmaInterruptCH1));
}
-/* tasklet handler: DMA data to dmx.*/
-static void smi_dma_xfer(struct tasklet_struct *t)
+/* BH work handler: DMA data to dmx.*/
+static void smi_dma_xfer(struct work_struct *t)
{
- struct smi_port *port = from_tasklet(port, t, tasklet);
+ struct smi_port *port = from_work(port, t, bh_work);
struct smi_dev *dev = port->dev;
u32 intr_status, finishedData, dmaManagement;
u8 dmaChan0State, dmaChan1State;
@@ -426,8 +426,8 @@ static int smi_port_init(struct smi_port *port, int dmaChanUsed)
}
smi_port_disableInterrupt(port);
- tasklet_setup(&port->tasklet, smi_dma_xfer);
- tasklet_disable(&port->tasklet);
+ INIT_WORK(&port->bh_work, smi_dma_xfer);
+ disable_work_sync(&port->bh_work);
port->enable = 1;
return 0;
err:
@@ -438,7 +438,7 @@ err:
static void smi_port_exit(struct smi_port *port)
{
smi_port_disableInterrupt(port);
- tasklet_kill(&port->tasklet);
+ cancel_work_sync(&port->bh_work);
smi_port_dma_free(port);
port->enable = 0;
}
@@ -452,7 +452,7 @@ static int smi_port_irq(struct smi_port *port, u32 int_status)
smi_port_disableInterrupt(port);
port->_int_status = int_status;
smi_port_clearInterrupt(port);
- tasklet_schedule(&port->tasklet);
+ queue_work(system_bh_wq, &port->bh_work);
handled = 1;
}
return handled;
@@ -823,7 +823,7 @@ static int smi_start_feed(struct dvb_demux_feed *dvbdmxfeed)
smi_port_clearInterrupt(port);
smi_port_enableInterrupt(port);
smi_write(port->DMA_MANAGEMENT, dmaManagement);
- tasklet_enable(&port->tasklet);
+ enable_and_queue_work(system_bh_wq, &port->bh_work);
}
return port->users;
}
@@ -837,7 +837,7 @@ static int smi_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
if (--port->users)
return port->users;
- tasklet_disable(&port->tasklet);
+ disable_work_sync(&port->bh_work);
smi_port_disableInterrupt(port);
smi_clear(port->DMA_MANAGEMENT, 0x30003);
return 0;
diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
index 2b5e0154814c..98e44edaab9e 100644
--- a/drivers/media/pci/smipcie/smipcie.h
+++ b/drivers/media/pci/smipcie/smipcie.h
@@ -17,6 +17,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
#include <media/rc-core.h>
#include <media/demux.h>
@@ -257,7 +258,7 @@ struct smi_port {
u32 _dmaInterruptCH0;
u32 _dmaInterruptCH1;
u32 _int_status;
- struct tasklet_struct tasklet;
+ struct work_struct bh_work;
/* dvb */
struct dmx_frontend hw_frontend;
struct dmx_frontend mem_frontend;
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 2e62c938e2cb..69f5e810f9b5 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -36,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/spinlock.h>
+#include <linux/workqueue.h>
#include <media/dvb_ca_en50221.h>
@@ -54,7 +55,7 @@ struct budget_av {
struct video_device vd;
int cur_input;
int has_saa7113;
- struct tasklet_struct ciintf_irq_tasklet;
+ struct work_struct ciintf_irq_bh_work;
int slot_status;
struct dvb_ca_en50221 ca;
u8 reinitialise_demod:1;
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 76de40e3c802..33f08adf4feb 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/workqueue.h>
#include <media/rc-core.h>
#include "budget.h"
@@ -81,7 +82,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct budget_ci_ir {
struct rc_dev *dev;
- struct tasklet_struct msp430_irq_tasklet;
+ struct work_struct msp430_irq_bh_work;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32];
int rc5_device;
@@ -92,7 +93,7 @@ struct budget_ci_ir {
struct budget_ci {
struct budget budget;
- struct tasklet_struct ciintf_irq_tasklet;
+ struct work_struct ciintf_irq_bh_work;
int slot_status;
int ci_irq;
struct dvb_ca_en50221 ca;
@@ -100,9 +101,9 @@ struct budget_ci {
u8 tuner_pll_address; /* used for philips_tdm1316l configs */
};
-static void msp430_ir_interrupt(struct tasklet_struct *t)
+static void msp430_ir_interrupt(struct work_struct *t)
{
- struct budget_ci_ir *ir = from_tasklet(ir, t, msp430_irq_tasklet);
+ struct budget_ci_ir *ir = from_work(ir, t, msp430_irq_bh_work);
struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir);
struct rc_dev *dev = budget_ci->ir.dev;
u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
@@ -231,7 +232,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
budget_ci->ir.dev = dev;
- tasklet_setup(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt);
+ INIT_WORK(&budget_ci->ir.msp430_irq_bh_work, msp430_ir_interrupt);
SAA7146_IER_ENABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
@@ -245,7 +246,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
SAA7146_IER_DISABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
- tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
+ cancel_work_sync(&budget_ci->ir.msp430_irq_bh_work);
rc_unregister_device(budget_ci->ir.dev);
}
@@ -349,10 +350,10 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
return 0;
}
-static void ciintf_interrupt(struct tasklet_struct *t)
+static void ciintf_interrupt(struct work_struct *t)
{
- struct budget_ci *budget_ci = from_tasklet(budget_ci, t,
- ciintf_irq_tasklet);
+ struct budget_ci *budget_ci = from_work(budget_ci, t,
+ ciintf_irq_bh_work);
struct saa7146_dev *saa = budget_ci->budget.dev;
unsigned int flags;
@@ -491,7 +492,7 @@ static int ciintf_init(struct budget_ci *budget_ci)
// Setup CI slot IRQ
if (budget_ci->ci_irq) {
- tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt);
+ INIT_WORK(&budget_ci->ciintf_irq_bh_work, ciintf_interrupt);
if (budget_ci->slot_status != SLOTSTATUS_NONE)
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
else
@@ -530,7 +531,7 @@ static void ciintf_deinit(struct budget_ci *budget_ci)
if (budget_ci->ci_irq) {
SAA7146_IER_DISABLE(saa, MASK_03);
saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
- tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+ cancel_work_sync(&budget_ci->ciintf_irq_bh_work);
}
// reset interface
@@ -556,13 +557,13 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 *isr)
dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
if (*isr & MASK_06)
- tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
+ queue_work(system_bh_wq, &budget_ci->ir.msp430_irq_bh_work);
if (*isr & MASK_10)
ttpci_budget_irq10_handler(dev, isr);
if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
- tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
+ queue_work(system_bh_wq, &budget_ci->ciintf_irq_bh_work);
}
static u8 philips_su1278_tt_inittab[] = {
diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c
index d33adeca196f..29531d9c9db0 100644
--- a/drivers/media/pci/ttpci/budget-core.c
+++ b/drivers/media/pci/ttpci/budget-core.c
@@ -172,9 +172,9 @@ static int budget_read_fe_status(struct dvb_frontend *fe,
return ret;
}
-static void vpeirq(struct tasklet_struct *t)
+static void vpeirq(struct work_struct *t)
{
- struct budget *budget = from_tasklet(budget, t, vpe_tasklet);
+ struct budget *budget = from_work(budget, t, vpe_bh_work);
u8 *mem = (u8 *) (budget->grabbing);
u32 olddma = budget->ttbp;
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
@@ -525,7 +525,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
/* upload all */
saa7146_write(dev, GPIO_CTRL, 0x000000);
- tasklet_setup(&budget->vpe_tasklet, vpeirq);
+ INIT_WORK(&budget->vpe_bh_work, vpeirq);
/* frontend power on */
if (bi->type != BUDGET_FS_ACTIVY)
@@ -565,7 +565,7 @@ int ttpci_budget_deinit(struct budget *budget)
budget_unregister(budget);
- tasklet_kill(&budget->vpe_tasklet);
+ cancel_work_sync(&budget->vpe_bh_work);
saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
@@ -584,7 +584,7 @@ void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 *isr)
dprintk(8, "dev: %p, budget: %p\n", dev, budget);
if (*isr & MASK_10)
- tasklet_schedule(&budget->vpe_tasklet);
+ queue_work(system_bh_wq, &budget->vpe_bh_work);
}
EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
@@ -602,4 +602,5 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
}
EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
+MODULE_DESCRIPTION("base driver for the SAA7146 based Budget DVB cards");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
index 83ead34dc766..e933764ac4e3 100644
--- a/drivers/media/pci/ttpci/budget.h
+++ b/drivers/media/pci/ttpci/budget.h
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/workqueue.h>
#include <media/drv-intf/saa7146.h>
@@ -54,8 +55,8 @@ struct budget {
unsigned char *grabbing;
struct saa7146_pgtable pt;
- struct tasklet_struct fidb_tasklet;
- struct tasklet_struct vpe_tasklet;
+ struct work_struct fidb_bh_work;
+ struct work_struct vpe_bh_work;
struct dmxdev dmxdev;
struct dvb_demux demux;
diff --git a/drivers/media/pci/tw5864/tw5864-core.c b/drivers/media/pci/tw5864/tw5864-core.c
index 560ff1ddcc83..4d33caf83307 100644
--- a/drivers/media/pci/tw5864/tw5864-core.c
+++ b/drivers/media/pci/tw5864/tw5864-core.c
@@ -144,7 +144,7 @@ static void tw5864_h264_isr(struct tw5864_dev *dev)
cur_frame->gop_seqno = input->frame_gop_seqno;
dev->h264_buf_w_index = next_frame_index;
- tasklet_schedule(&dev->tasklet);
+ queue_work(system_bh_wq, &dev->bh_work);
cur_frame = next_frame;
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c
index 8b1aae4b6319..4f35c159efe5 100644
--- a/drivers/media/pci/tw5864/tw5864-video.c
+++ b/drivers/media/pci/tw5864/tw5864-video.c
@@ -6,6 +6,7 @@
*/
#include <linux/module.h>
+#include <linux/workqueue.h>
#include <media/v4l2-common.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-dma-contig.h>
@@ -175,7 +176,7 @@ static const unsigned int intra4x4_lambda3[] = {
static v4l2_std_id tw5864_get_v4l2_std(enum tw5864_vid_std std);
static enum tw5864_vid_std tw5864_from_v4l2_std(v4l2_std_id v4l2_std);
-static void tw5864_handle_frame_task(struct tasklet_struct *t);
+static void tw5864_handle_frame_work(struct work_struct *t);
static void tw5864_handle_frame(struct tw5864_h264_frame *frame);
static void tw5864_frame_interval_set(struct tw5864_input *input);
@@ -1062,7 +1063,7 @@ int tw5864_video_init(struct tw5864_dev *dev, int *video_nr)
dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER;
tw5864_irqmask_apply(dev);
- tasklet_setup(&dev->tasklet, tw5864_handle_frame_task);
+ INIT_WORK(&dev->bh_work, tw5864_handle_frame_work);
for (i = 0; i < TW5864_INPUTS; i++) {
dev->inputs[i].root = dev;
@@ -1079,7 +1080,7 @@ fini_video_inputs:
for (i = last_input_nr_registered; i >= 0; i--)
tw5864_video_input_fini(&dev->inputs[i]);
- tasklet_kill(&dev->tasklet);
+ cancel_work_sync(&dev->bh_work);
free_dma:
for (i = last_dma_allocated; i >= 0; i--) {
@@ -1198,7 +1199,7 @@ void tw5864_video_fini(struct tw5864_dev *dev)
{
int i;
- tasklet_kill(&dev->tasklet);
+ cancel_work_sync(&dev->bh_work);
for (i = 0; i < TW5864_INPUTS; i++)
tw5864_video_input_fini(&dev->inputs[i]);
@@ -1315,9 +1316,9 @@ static int tw5864_is_motion_triggered(struct tw5864_h264_frame *frame)
return detected;
}
-static void tw5864_handle_frame_task(struct tasklet_struct *t)
+static void tw5864_handle_frame_work(struct work_struct *t)
{
- struct tw5864_dev *dev = from_tasklet(dev, t, tasklet);
+ struct tw5864_dev *dev = from_work(dev, t, bh_work);
unsigned long flags;
int batch_size = H264_BUF_CNT;
diff --git a/drivers/media/pci/tw5864/tw5864.h b/drivers/media/pci/tw5864/tw5864.h
index a8b6fbd5b710..2da5f4215fd9 100644
--- a/drivers/media/pci/tw5864/tw5864.h
+++ b/drivers/media/pci/tw5864/tw5864.h
@@ -12,6 +12,7 @@
#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/interrupt.h>
+#include <linux/workqueue.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
@@ -85,7 +86,7 @@ struct tw5864_input {
int nr; /* input number */
struct tw5864_dev *root;
struct mutex lock; /* used for vidq and vdev */
- spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */
+ spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */
struct video_device vdev;
struct v4l2_ctrl_handler hdl;
struct vb2_queue vidq;
@@ -142,7 +143,7 @@ struct tw5864_h264_frame {
/* global device status */
struct tw5864_dev {
- spinlock_t slock; /* used for sync between ISR, tasklet & V4L2 API */
+ spinlock_t slock; /* used for sync between ISR, bh_work & V4L2 API */
struct v4l2_device v4l2_dev;
struct tw5864_input inputs[TW5864_INPUTS];
#define H264_BUF_CNT 4
@@ -150,7 +151,7 @@ struct tw5864_dev {
int h264_buf_r_index;
int h264_buf_w_index;
- struct tasklet_struct tasklet;
+ struct work_struct bh_work;
int encoder_busy;
/* Input number to check next for ready raw picture (in RR fashion) */