diff --git a/Documentation/video4linux/v4lgrab.c b/Documentation/video4linux/v4lgrab.c
index 079b628481cf6a566a47b071ba354b6d3d0a1910..d6e70bef8ad0a98d040b8dd5cb5a3272a233f7bb 100644
--- a/Documentation/video4linux/v4lgrab.c
+++ b/Documentation/video4linux/v4lgrab.c
@@ -4,12 +4,21 @@
  *
  *	Compile with:
  *		gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
- *      Use as:
- *              v4lgrab >image.ppm
+ *	Use as:
+ *		v4lgrab >image.ppm
  *
  *	Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
- *      Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
- *      with minor modifications (Dave Forrest, drf5n@virginia.edu).
+ *	Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
+ *	with minor modifications (Dave Forrest, drf5n@virginia.edu).
+ *
+ *
+ *	For some cameras you may need to pre-load libv4l to perform
+ *	the necessary decompression, e.g.:
+ *
+ *	export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
+ *	./v4lgrab >image.ppm
+ *
+ *	see http://hansdegoede.livejournal.com/3636.html for details.
  *
  */
 
@@ -24,7 +33,7 @@
 #include <linux/types.h>
 #include <linux/videodev.h>
 
-#define FILE "/dev/video0"
+#define VIDEO_DEV "/dev/video0"
 
 /* Stole this from tvset.c */
 
@@ -90,7 +99,7 @@ int get_brightness_adj(unsigned char *image, long size, int *brightness) {
 
 int main(int argc, char ** argv)
 {
-  int fd = open(FILE, O_RDONLY), f;
+  int fd = open(VIDEO_DEV, O_RDONLY), f;
   struct video_capability cap;
   struct video_window win;
   struct video_picture vpic;
@@ -100,13 +109,13 @@ int main(int argc, char ** argv)
   unsigned int i, src_depth;
 
   if (fd < 0) {
-    perror(FILE);
+    perror(VIDEO_DEV);
     exit(1);
   }
 
   if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
     perror("VIDIOGCAP");
-    fprintf(stderr, "(" FILE " not a video4linux device?)\n");
+    fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
     close(fd);
     exit(1);
   }
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 6098b626811fac4baa0e89f40b0e45e371c9b56f..47fee05eaefbab9a67492f5c97067a5874fa341e 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -576,6 +576,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
 		vv->vflip = c->value;
 		break;
 	default: {
+		mutex_unlock(&dev->lock);
 		return -EINVAL;
 	}
 	}
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 64379f2bf2370eaf221d33aea24a7c946ab75f5a..3ec28945c26f21b7e0d7cc8d48c772aba35c384d 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -657,7 +657,7 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
 	int rf_locked, ref_locked;
-	s32 rf_input_level;
+	s32 rf_input_level = 0;
 	int ret;
 
 	if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 98ee16773ff2e204e82f3501f0f0ed45d123b844..7e3aeaa7370f3a6ed3bf45700694e1c6fddae322 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -93,6 +93,9 @@ struct dvb_ca_slot {
 	/* current state of the CAM */
 	int slot_state;
 
+	/* mutex used for serializing access to one CI slot */
+	struct mutex slot_lock;
+
 	/* Number of CAMCHANGES that have occurred since last processing */
 	atomic_t camchange_count;
 
@@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
 	dprintk("%s\n", __func__);
 
 
-	// sanity check
+	/* sanity check */
 	if (bytes_write > ca->slot_info[slot].link_buf_size)
 		return -EINVAL;
 
-	/* check if interface is actually waiting for us to read from it, or if a read is in progress */
+	/* it is possible we are dealing with a single buffer implementation,
+	   thus if there is data available for read or if there is even a read
+	   already in progress, we do nothing but awake the kernel thread to
+	   process the data if necessary. */
 	if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
 		goto exitnowrite;
 	if (status & (STATUSREG_DA | STATUSREG_RE)) {
+		if (status & STATUSREG_DA)
+			dvb_ca_en50221_thread_wakeup(ca);
+
 		status = -EAGAIN;
 		goto exitnowrite;
 	}
@@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
 		/* go through all the slots processing them */
 		for (slot = 0; slot < ca->slot_count; slot++) {
 
+			mutex_lock(&ca->slot_info[slot].slot_lock);
+
 			// check the cam status + deal with CAMCHANGEs
 			while (dvb_ca_en50221_check_camstatus(ca, slot)) {
 				/* clear down an old CI slot if necessary */
@@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)
 
 			case DVB_CA_SLOTSTATE_RUNNING:
 				if (!ca->open)
-					continue;
+					break;
 
 				// poll slots for data
 				pktcount = 0;
@@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
 				}
 				break;
 			}
+
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 		}
 	}
 
@@ -1181,6 +1194,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
 	switch (cmd) {
 	case CA_RESET:
 		for (slot = 0; slot < ca->slot_count; slot++) {
+			mutex_lock(&ca->slot_info[slot].slot_lock);
 			if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
 				dvb_ca_en50221_slot_shutdown(ca, slot);
 				if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
@@ -1188,6 +1202,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
 								     slot,
 								     DVB_CA_EN50221_CAMCHANGE_INSERTED);
 			}
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 		}
 		ca->next_read_slot = 0;
 		dvb_ca_en50221_thread_wakeup(ca);
@@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
 				goto exit;
 			}
 
+			mutex_lock(&ca->slot_info[slot].slot_lock);
 			status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
+			mutex_unlock(&ca->slot_info[slot].slot_lock);
 			if (status == (fraglen + 2)) {
 				written = 1;
 				break;
@@ -1664,6 +1681,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 		ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
 		atomic_set(&ca->slot_info[i].camchange_count, 0);
 		ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+		mutex_init(&ca->slot_info[i].slot_lock);
 	}
 
 	if (signal_pending(current)) {
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
index 8467e63ddc0d256c2dda250f49786979f06e53b6..7df2e141187a9183d6ab46bba817c6a985319e10 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
 	/* the module owning this structure */
 	struct module* owner;
 
-	/* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
-	 * they may be called from several threads at once */
+	/* NOTE: the read_*, write_* and poll_slot_status functions will be
+	 * called for different slots concurrently and need to use locks where
+	 * and if appropriate. There will be no concurrent access to one slot.
+	 */
 
 	/* functions for accessing attribute memory on the CAM */
 	int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
index b1a9c4cdec93ee27f8eec60f6f7dcf5774836c4e..199ece0d48837125da59e7495e81ad2035f47a47 100644
--- a/drivers/media/dvb/dvb-usb/af9005-fe.c
+++ b/drivers/media/dvb/dvb-usb/af9005-fe.c
@@ -220,7 +220,7 @@ static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
 				   u16 * abort_count)
 {
 	u32 loc_cw_count = 0, loc_err_count;
-	u16 loc_abort_count;
+	u16 loc_abort_count = 0;
 	int ret;
 
 	ret =
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index e1e9aa5c6b843991c13ba4286ed92d650b728e97..6a97a40d3dfbcf63dc793df361451cb9e0f29607 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -694,7 +694,12 @@ static int af9015_read_config(struct usb_device *udev)
 
 	/* IR remote controller */
 	req.addr = AF9015_EEPROM_IR_MODE;
-	ret = af9015_rw_udev(udev, &req);
+	/* first message will timeout often due to possible hw bug */
+	for (i = 0; i < 4; i++) {
+		ret = af9015_rw_udev(udev, &req);
+		if (!ret)
+			break;
+	}
 	if (ret)
 		goto error;
 	deb_info("%s: IR mode:%d\n", __func__, val);
@@ -835,18 +840,19 @@ static int af9015_read_config(struct usb_device *udev)
 	if (!dvb_usb_af9015_dual_mode)
 		af9015_config.dual_mode = 0;
 
-	/* set buffer size according to USB port speed */
+	/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
+	   size can be static because it is enabled only USB2.0 */
 	for (i = 0; i < af9015_properties_count; i++) {
 		/* USB1.1 set smaller buffersize and disable 2nd adapter */
 		if (udev->speed == USB_SPEED_FULL) {
-			af9015_properties[i].adapter->stream.u.bulk.buffersize =
-				TS_USB11_MAX_PACKET_SIZE;
+			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+				= TS_USB11_MAX_PACKET_SIZE;
 			/* disable 2nd adapter because we don't have
 			   PID-filters */
 			af9015_config.dual_mode = 0;
 		} else {
-			af9015_properties[i].adapter->stream.u.bulk.buffersize =
-				TS_USB20_MAX_PACKET_SIZE;
+			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+				= TS_USB20_MAX_PACKET_SIZE;
 		}
 	}
 
@@ -1254,6 +1260,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.type = USB_BULK,
 					.count = 6,
 					.endpoint = 0x85,
+					.u = {
+						.bulk = {
+							.buffersize =
+						TS_USB20_MAX_PACKET_SIZE,
+						}
+					}
 				},
 			}
 		},
@@ -1353,6 +1365,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.type = USB_BULK,
 					.count = 6,
 					.endpoint = 0x85,
+					.u = {
+						.bulk = {
+							.buffersize =
+						TS_USB20_MAX_PACKET_SIZE,
+						}
+					}
 				},
 			}
 		},
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 3917327889117bcff8cf27f315c8a3d70fcb27c7..635d30a55078d52c76804581cddb6ae4ee0a485c 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1393,6 +1393,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
 	{ USB_DEVICE(USB_VID_ASUS,	USB_PID_ASUS_U3000H) },
 /* 40 */{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV801E_SE) },
+	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
+	{ USB_DEVICE(USB_VID_TERRATEC,
+			USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1537,7 +1540,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "DiBcom STK7700D reference design",
 				{ &dib0700_usb_id_table[14], NULL },
 				{ NULL },
-			}
+			},
+
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -1557,7 +1561,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			},
 		},
 
-		.num_device_descs = 2,
+		.num_device_descs = 3,
 		.devices = {
 			{   "ASUS My Cinema U3000 Mini DVBT Tuner",
 				{ &dib0700_usb_id_table[23], NULL },
@@ -1566,6 +1570,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "Yuan EC372S",
 				{ &dib0700_usb_id_table[31], NULL },
 				{ NULL },
+			},
+			{   "Terratec Cinergy T Express",
+				{ &dib0700_usb_id_table[42], NULL },
+				{ NULL },
 			}
 		},
 
@@ -1653,7 +1661,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			}
 		},
 
-		.num_device_descs = 4,
+		.num_device_descs = 5,
 		.devices = {
 			{   "DiBcom STK7070PD reference design",
 				{ &dib0700_usb_id_table[17], NULL },
@@ -1670,6 +1678,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			{   "Hauppauge Nova-TD-500 (84xxx)",
 				{ &dib0700_usb_id_table[36], NULL },
 				{ NULL },
+			},
+			{  "Terratec Cinergy DT USB XS Diversity",
+				{ &dib0700_usb_id_table[43], NULL },
+				{ NULL },
 			}
 		}
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a4fca3fca5eede1e7c1c4913a7905d72738b804b..0db0c06ee6f2dcf0783eafb3982a14c37643d110 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -162,8 +162,10 @@
 #define USB_PID_AVERMEDIA_A309				0xa309
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081
 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
 #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
+#define USB_PID_TERRATEC_CINERGY_T_EXPRESS		0x0062
 #define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
 #define USB_PID_PINNACLE_PCTV2000E			0x022c
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index ec4e08dbc699c78a31432a470d1292d1261ca312..1e81e713df635db0e310d3419c557c5bcce56fb1 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -646,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s,
 	u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
 	u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
 
-	int rc, df_tuner;
+	int rc, df_tuner = 0;
 	int a, b, c, d;
 	pr_debug("%s %d\n", __func__, s->config.d60);
 
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index cf4d8936bb83f515b49cbb300c9a892bb24a28fb..3e08d985d6e50cf2f1fb36df3169274c74b22dcb 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
 
 	s5h1409_enable_modulation(fe, p->u.vsb.modulation);
 
-	/* Allow the demod to settle */
-	msleep(100);
-
 	if (fe->ops.tuner_ops.set_params) {
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 1);
@@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
 		s5h1409_set_qam_interleave_mode(fe);
 	}
 
+	/* Issue a reset to the demod so it knows to resync against the
+	   newly tuned frequency */
+	s5h1409_softreset(fe);
+
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index 83dc7e12d5f0a3c8763788ab2a408032e89c00bd..a67d1775a43ceb2f6cdb17e1dcb8ecba55fb95d4 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d)
 	return n;
 }
 
+#if 0
+/* These functions are currently unused */
 /*
  * stb0899_calc_srate
  * Compute symbol rate
@@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state)
 
 	return stb0899_calc_srate(internal->master_clk, sfr);
 }
+#endif
 
 /*
  * stb0899_set_srate
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1638e1d9f538011e49a193b6ce52dbf86464d274..83e9e7750c8cb1e382ddda99e901f7fef1514d48 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -470,6 +470,7 @@ static void frontend_init(struct budget *budget)
 		budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+			budget->dvb_frontend->tuner_priv = NULL;
 			break;
 		}
 		break;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 0aa96df80fc2bad8337263e1c23cc9b234f78885..d91e0638448fce9adb1a25d5e0091bf5804ae3f9 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1384,7 +1384,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
 static int ttusb_dec_init_stb(struct ttusb_dec *dec)
 {
 	int result;
-	unsigned int mode, model, version;
+	unsigned int mode = 0, model = 0, version = 0;
 
 	dprintk("%s\n", __func__);
 
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 0747dc8862b095718e3dba02bd32be898227f829..fdfc7bf86b9e15c498ea4fc57eef55f304e6f67c 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -194,10 +194,10 @@ static int amradio_start(struct amradio_device *radio)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->muted = 0;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
@@ -230,10 +230,10 @@ static int amradio_stop(struct amradio_device *radio)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->muted = 1;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
@@ -284,10 +284,10 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
 		return retval;
 	}
 
-	mutex_unlock(&radio->lock);
-
 	radio->stereo = 0;
 
+	mutex_unlock(&radio->lock);
+
 	return retval;
 }
 
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 14bebf8a116ffe2b4afc6546bc80eb66ef2b110d..87e91072627ad934fec33920defb54fa05b1d64e 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -18,7 +18,6 @@
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8f1db57bd1dd8cefc4fcd7b55865429ec04491bd..bfe25841dbf483239777cd72dddcbafb8e087a39 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file)
 	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->v4l_device->minor == minor) {
+		if (h->v4l_device &&
+		    h->v4l_device->minor == minor) {
 			dev = h;
 			break;
 		}
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 2d81c4d043403297b504a2b77b5a17560cde31c7..eaa11893bfe918f23e1ca7403179c7d2ec975680 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -730,12 +730,13 @@ static int video_open(struct file *file)
 	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
-		if (h->video_dev->minor == minor) {
+		if (h->video_dev &&
+		    h->video_dev->minor == minor) {
 			dev  = h;
 			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 		}
 		if (h->vbi_dev &&
-		   h->vbi_dev->minor == minor) {
+		    h->vbi_dev->minor == minor) {
 			dev  = h;
 			type = V4L2_BUF_TYPE_VBI_CAPTURE;
 		}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 88f2fd32bfe357617f82f011df18a9c31ddf7997..25eb3bec9e5d9dde1ef7051482dbc7d7e2e7c94a 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1382,6 +1382,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
 
 static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
+	/* ignore this command */
+	if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
+		return 0;
+
+	/* Old-style drivers rely on initialization on first use, so
+	   call the init whenever a command is issued to this driver.
+	   New-style drivers using v4l2_subdev should call init explicitly. */
+	cx25840_init(i2c_get_clientdata(client), 0);
 	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
 }
 
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 613dfea4ff3e551a6cd0ab51d79c623b3902fdbf..aef5297534af95f7101ec065040f68cdf222bca7 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -614,34 +614,41 @@ static struct stv0288_config tevii_tuner_earda_config = {
 	.set_ts_params = cx24116_set_ts_param,
 };
 
-static int dvb_register(struct cx8802_dev *dev)
+static int cx8802_alloc_frontends(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
-	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
-	int mfe_shared = 0; /* bus not shared by default */
+	struct videobuf_dvb_frontend *fe = NULL;
 	int i;
 
-	if (0 != core->i2c_rc) {
-		printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
-		goto frontend_detach;
-	}
-
-	if (!core->board.num_frontends)
-		return -EINVAL;
-
 	mutex_init(&dev->frontends.lock);
 	INIT_LIST_HEAD(&dev->frontends.felist);
 
+	if (!core->board.num_frontends)
+		return -ENODEV;
+
 	printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
 			 core->board.num_frontends);
 	for (i = 1; i <= core->board.num_frontends; i++) {
-		fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
-		if (!fe0) {
+		fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+		if (!fe) {
 			printk(KERN_ERR "%s() failed to alloc\n", __func__);
 			videobuf_dvb_dealloc_frontends(&dev->frontends);
-			goto frontend_detach;
+			return -ENOMEM;
 		}
 	}
+	return 0;
+}
+
+static int dvb_register(struct cx8802_dev *dev)
+{
+	struct cx88_core *core = dev->core;
+	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+	int mfe_shared = 0; /* bus not shared by default */
+
+	if (0 != core->i2c_rc) {
+		printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
+		goto frontend_detach;
+	}
 
 	/* Get the first frontend */
 	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
@@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 	struct cx88_core *core = drv->core;
 	struct cx8802_dev *dev = drv->core->dvbdev;
 	int err;
+	struct videobuf_dvb_frontend *fe;
+	int i;
 
 	dprintk( 1, "%s\n", __func__);
 	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 	/* If vp3054 isn't enabled, a stub will just return 0 */
 	err = vp3054_i2c_probe(dev);
 	if (0 != err)
-		goto fail_probe;
+		goto fail_core;
 
 	/* dvb stuff */
 	printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
 	dev->ts_gen_cntrl = 0x0c;
 
+	err = cx8802_alloc_frontends(dev);
+	if (err)
+		goto fail_core;
+
 	err = -ENODEV;
-	if (core->board.num_frontends) {
-		struct videobuf_dvb_frontend *fe;
-		int i;
-
-		for (i = 1; i <= core->board.num_frontends; i++) {
-			fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
-			if (fe == NULL) {
-				printk(KERN_ERR "%s() failed to get frontend(%d)\n",
+	for (i = 1; i <= core->board.num_frontends; i++) {
+		fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+		if (fe == NULL) {
+			printk(KERN_ERR "%s() failed to get frontend(%d)\n",
 					__func__, i);
-				goto fail_probe;
-			}
-			videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
+			goto fail_probe;
+		}
+		videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
 				    &dev->pci->dev, &dev->slock,
 				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				    V4L2_FIELD_TOP,
 				    sizeof(struct cx88_buffer),
 				    dev);
-			/* init struct videobuf_dvb */
-			fe->dvb.name = dev->core->name;
-		}
-	} else {
-		/* no frontends allocated */
-		printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
-			core->name);
-		goto fail_core;
+		/* init struct videobuf_dvb */
+		fe->dvb.name = dev->core->name;
 	}
+
 	err = dvb_register(dev);
 	if (err)
 		/* frontends/adapter de-allocated in dvb_register */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 60a8b3187f14bd0e0c097caafd4fa6adceaf5e85..6025fdd233445857d571632126399566acbc6a0b 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -336,8 +336,8 @@ struct cx88_core {
 	/* config info -- dvb */
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 	int 			   (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-	void			   (*gate_ctrl)(struct cx88_core  *core, int open);
 #endif
+	void			   (*gate_ctrl)(struct cx88_core  *core, int open);
 
 	/* state info */
 	struct task_struct         *kthread;
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 94378ccb7505845d157920e4f81d9154eee6f35f..5d882a44e3eee5444c00062f3e5edf70b118cc4e 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -62,9 +62,15 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
 
 	dprintk("Stopping isoc\n");
 	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
-		usb_unlink_urb(dev->adev.urb[i]);
+		if (!irqs_disabled())
+			usb_kill_urb(dev->adev.urb[i]);
+		else
+			usb_unlink_urb(dev->adev.urb[i]);
 		usb_free_urb(dev->adev.urb[i]);
 		dev->adev.urb[i] = NULL;
+
+		kfree(dev->adev.transfer_buffer[i]);
+		dev->adev.transfer_buffer[i] = NULL;
 	}
 
 	return 0;
@@ -389,11 +395,15 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
 static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
 						    *substream)
 {
-	struct em28xx *dev;
+       unsigned long flags;
 
+	struct em28xx *dev;
 	snd_pcm_uframes_t hwptr_done;
+
 	dev = snd_pcm_substream_chip(substream);
+       spin_lock_irqsave(&dev->adev.slock, flags);
 	hwptr_done = dev->adev.hwptr_done_capture;
+       spin_unlock_irqrestore(&dev->adev.slock, flags);
 
 	return hwptr_done;
 }
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ef9bf008a924731f9f7e4728087d0a5050606e26..3b3ca3f46d52e1f78e67a94dc831d0565be92dd4 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
 /* Board  - EM2870 Kworld 355u
    Analog - No input analog */
 
+static struct em28xx_reg_seq kworld_330u_analog[] = {
+	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x00,	0xff,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
+static struct em28xx_reg_seq kworld_330u_digital[] = {
+	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x08,	0xff,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
 	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
@@ -1177,29 +1189,33 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = hauppauge_wintv_hvr_900_analog,
 		} },
 	},
-	[EM2883_BOARD_KWORLD_HYBRID_A316] = {
+	[EM2883_BOARD_KWORLD_HYBRID_330U] = {
 		.name         = "Kworld PlusTV HD Hybrid 330",
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.decoder      = EM28XX_TVP5150,
 		.mts_firmware = 1,
 		.has_dvb      = 1,
-		.dvb_gpio     = default_digital,
+		.dvb_gpio     = kworld_330u_digital,
+		.xclk             = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.i2c_speed        = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
 			.amux     = EM28XX_AMUX_VIDEO,
-			.gpio     = default_analog,
+			.gpio     = kworld_330u_analog,
+			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
 		}, {
 			.type     = EM28XX_VMUX_COMPOSITE1,
 			.vmux     = TVP5150_COMPOSITE1,
 			.amux     = EM28XX_AMUX_LINE_IN,
-			.gpio     = hauppauge_wintv_hvr_900_analog,
+			.gpio     = kworld_330u_analog,
+			.aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
 		}, {
 			.type     = EM28XX_VMUX_SVIDEO,
 			.vmux     = TVP5150_SVIDEO,
 			.amux     = EM28XX_AMUX_LINE_IN,
-			.gpio     = hauppauge_wintv_hvr_900_analog,
+			.gpio     = kworld_330u_analog,
 		} },
 	},
 	[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
@@ -1249,7 +1265,7 @@ struct usb_device_id em28xx_id_table [] = {
 	{ USB_DEVICE(0xeb1a, 0xe310),
 			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
 	{ USB_DEVICE(0xeb1a, 0xa316),
-			.driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+			.driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
 	{ USB_DEVICE(0xeb1a, 0xe320),
 			.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
 	{ USB_DEVICE(0xeb1a, 0xe323),
@@ -1526,6 +1542,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
 		/* FIXME: Better to specify the needed IF */
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
+	case EM2883_BOARD_KWORLD_HYBRID_330U:
+		ctl->demod = XC3028_FE_CHINA;
+		ctl->fname = XC2028_DEFAULT_FIRMWARE;
+		break;
 	default:
 		ctl->demod = XC3028_FE_OREN538;
 	}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index eb5fb05fab22b5ade17e07f9697549e1dbaa9dd3..94fb1b639a2e4c52762544a0cefb34b9486909b4 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 	if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
 		int vol;
 
+		em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
+		em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
+		em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
+
 		/* LSB: left channel - both channels with the same level */
 		vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
 
@@ -454,6 +458,15 @@ int em28xx_audio_analog_set(struct em28xx *dev)
 				em28xx_warn("couldn't setup AC97 register %d\n",
 				     outputs[i].reg);
 		}
+
+		if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
+			int sel = ac97_return_record_select(dev->ctl_aoutput);
+
+			/* Use the same input for both left and right channels */
+			sel |= (sel << 8);
+
+			em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
+		}
 	}
 
 	return ret;
@@ -847,8 +860,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
 	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
 		urb = dev->isoc_ctl.urb[i];
 		if (urb) {
-			usb_kill_urb(urb);
-			usb_unlink_urb(urb);
+			if (!irqs_disabled())
+				usb_kill_urb(urb);
+			else
+				usb_unlink_urb(urb);
+
 			if (dev->isoc_ctl.transfer_buffer[i]) {
 				usb_buffer_free(dev->udev,
 					urb->transfer_buffer_length,
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d38cb21834d9dd790d36bfb7c48e3b691fd5154b..9ad8527b3fda0b15c005edbe4ace40492687fde5 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -28,6 +28,7 @@
 
 #include "lgdt330x.h"
 #include "zl10353.h"
+#include "s5h1409.h"
 #ifdef EM28XX_DRX397XD_SUPPORT
 #include "drx397xD.h"
 #endif
@@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
 	.if2 = 45600,
 };
 
+static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
+	.demod_address = 0x32 >> 1,
+	.output_mode   = S5H1409_PARALLEL_OUTPUT,
+	.gpio          = S5H1409_GPIO_OFF,
+	.inversion     = S5H1409_INVERSION_OFF,
+	.status_mode   = S5H1409_DEMODLOCKING,
+	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+};
+
 #ifdef EM28XX_DRX397XD_SUPPORT
 /* [TODO] djh - not sure yet what the device config needs to contain */
 static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev)
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
-	case EM2883_BOARD_KWORLD_HYBRID_A316:
 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
 		dvb->frontend = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
@@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev)
 			goto out_free;
 		}
 		break;
+	case EM2883_BOARD_KWORLD_HYBRID_330U:
+		dvb->frontend = dvb_attach(s5h1409_attach,
+					   &em28xx_s5h1409_with_xc3028,
+					   &dev->i2c_adap);
+		if (attach_xc3028(0x61, dev) < 0) {
+			result = -EINVAL;
+			goto out_free;
+		}
+		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
 #ifdef EM28XX_DRX397XD_SUPPORT
 		/* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 416b691c33c1eafd382420fbc7dbb1af79ff64f3..8e61b2ca9167810b3b8db9f6f7b982be41bd369e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -886,10 +886,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 	if (0 == INPUT(i)->type)
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
-
-	video_mux(dev, i);
+	dev->ctl_input = i;
 
+	mutex_lock(&dev->lock);
+	video_mux(dev, dev->ctl_input);
 	mutex_unlock(&dev->lock);
 	return 0;
 }
@@ -939,6 +939,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	struct em28xx_fh   *fh  = priv;
 	struct em28xx      *dev = fh->dev;
 
+
+	if (a->index >= MAX_EM28XX_INPUT)
+		return -EINVAL;
+	if (0 == INPUT(a->index)->type)
+		return -EINVAL;
+
 	mutex_lock(&dev->lock);
 
 	dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1950,6 +1956,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
 
 int em28xx_register_analog_devices(struct em28xx *dev)
 {
+      u8 val;
 	int ret;
 
 	printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@@ -1957,34 +1964,34 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 		(EM28XX_VERSION_CODE >> 16) & 0xff,
 		(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
 
+	/* set default norm */
+	dev->norm = em28xx_video_template.current_norm;
+	dev->width = norm_maxw(dev);
+	dev->height = norm_maxh(dev);
+	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+	dev->hscale = 0;
+	dev->vscale = 0;
+	dev->ctl_input = 0;
+
 	/* Analog specific initialization */
 	dev->format = &format[0];
-	video_mux(dev, 0);
+	video_mux(dev, dev->ctl_input);
+
+	/* Audio defaults */
+	dev->mute = 1;
+	dev->volume = 0x1f;
 
 	/* enable vbi capturing */
 
 /*	em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-/*	em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+       val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+       em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
 	em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
-	dev->mute = 1;		/* maybe not the right place... */
-	dev->volume = 0x1f;
-
 	em28xx_set_outfmt(dev);
 	em28xx_colorlevels_set_default(dev);
 	em28xx_compression_disable(dev);
 
-	/* set default norm */
-	dev->norm = em28xx_video_template.current_norm;
-	dev->width = norm_maxw(dev);
-	dev->height = norm_maxh(dev);
-	dev->interlaced = EM28XX_INTERLACED_DEFAULT;
-	dev->hscale = 0;
-	dev->vscale = 0;
-
-	/* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
-	dev->ctl_input = 2;
-
 	/* allocate and fill video video_device struct */
 	dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
 	if (!dev->vdev) {
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6c6b94aa05b2ca2377d0672c3149095cd38661e1..dd2cd36fb1bbdcc1cab644e12b56b96e30d0041a 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -94,7 +94,7 @@
 #define EM2882_BOARD_KWORLD_VS_DVBT		  54
 #define EM2882_BOARD_TERRATEC_HYBRID_XS		  55
 #define EM2882_BOARD_PINNACLE_HYBRID_PRO	  56
-#define EM2883_BOARD_KWORLD_HYBRID_A316		  57
+#define EM2883_BOARD_KWORLD_HYBRID_330U                  57
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU	  58
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850	  60
 #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2	  61
@@ -300,13 +300,32 @@ enum em28xx_amux {
 };
 
 enum em28xx_aout {
+	/* AC97 outputs */
 	EM28XX_AOUT_MASTER = 1 << 0,
 	EM28XX_AOUT_LINE   = 1 << 1,
 	EM28XX_AOUT_MONO   = 1 << 2,
 	EM28XX_AOUT_LFE    = 1 << 3,
 	EM28XX_AOUT_SURR   = 1 << 4,
+
+	/* PCM IN Mixer - used by AC97_RECORD_SELECT register */
+	EM28XX_AOUT_PCM_IN = 1 << 7,
+
+	/* Bits 10-8 are used to indicate the PCM IN record select */
+	EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
+	EM28XX_AOUT_PCM_CD	= 1 << 8,
+	EM28XX_AOUT_PCM_VIDEO	= 2 << 8,
+	EM28XX_AOUT_PCM_AUX	= 3 << 8,
+	EM28XX_AOUT_PCM_LINE	= 4 << 8,
+	EM28XX_AOUT_PCM_STEREO	= 5 << 8,
+	EM28XX_AOUT_PCM_MONO	= 6 << 8,
+	EM28XX_AOUT_PCM_PHONE	= 7 << 8,
 };
 
+static inline int ac97_return_record_select(int a_out)
+{
+	return (a_out & 0x700) >> 8;
+}
+
 struct em28xx_reg_seq {
 	int reg;
 	unsigned char val, mask;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 5e36b9a4ae3ea289ee016af8041230ef622ef0bf..2ed24527ecd61cea70287dd668725445799ee4fa 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -423,7 +423,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
 			break;
 
 		gspca_dev->urb[i] = NULL;
-		usb_kill_urb(urb);
+		if (!gspca_dev->present)
+			usb_kill_urb(urb);
 		if (urb->transfer_buffer != NULL)
 			usb_buffer_free(gspca_dev->dev,
 					urb->transfer_buffer_length,
@@ -1950,7 +1951,6 @@ void gspca_disconnect(struct usb_interface *intf)
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 
 	gspca_dev->present = 0;
-	gspca_dev->streaming = 0;
 
 	usb_set_intfdata(intf, NULL);
 
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e8e5921cdc346dd8b26efa1ad93cc01f1791acdb..c46c990987f9b417a263e51782eb0ec3915b05a0 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -949,8 +949,10 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 	itv->instance = atomic_inc_return(&ivtv_instance) - 1;
 
 	retval = v4l2_device_register(&dev->dev, &itv->device);
-	if (retval)
+	if (retval) {
+		kfree(itv);
 		return retval;
+	}
 	/* "ivtv + PCI ID" is a bit of a mouthful, so use
 	   "ivtv + instance" instead. */
 	snprintf(itv->device.name, sizeof(itv->device.name),
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 39fbc970f43de09da5d45fd6951b82af337a2775..0d810189dd87836861e1974267137e6325e5b7e4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -62,7 +62,6 @@
 #include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
 #include <asm/io.h>
 
 #include "pwc.h"
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index d6848f7a503b5874e58259696f69f8033f89b407..05221d47dd4c9e464db5483c94d52435acd764b6 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
 	{ SAA7127_REG_COPYGEN_0, 			0x77 },
 	{ SAA7127_REG_COPYGEN_1, 			0x41 },
 	{ SAA7127_REG_COPYGEN_2, 			0x00 },	/* Macrovision enable/disable */
-	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0x9e },
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0xbf },
 	{ SAA7127_REG_GAIN_LUMINANCE_RGB, 		0x00 },
 	{ SAA7127_REG_GAIN_COLORDIFF_RGB, 		0x00 },
 	{ SAA7127_REG_INPUT_PORT_CONTROL_1, 		0x80 },	/* for color bars */
@@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
 		break;
 
 	case SAA7127_OUTPUT_TYPE_COMPOSITE:
-		state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x20;	/* CVBS only */
+		else
+			state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
 	case SAA7127_OUTPUT_TYPE_SVIDEO:
-		state->reg_2d = 0xff;	/* 11111111  croma -> R, luma -> CVBS + G + B */
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x18;	/* Y + C */
+		else
+			state->reg_2d = 0xff;   /*11111111  croma -> R, luma -> CVBS + G + B */
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
@@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
 		break;
 
 	case SAA7127_OUTPUT_TYPE_BOTH:
-		state->reg_2d = 0xbf;
+		if (state->ident == V4L2_IDENT_SAA7129)
+			state->reg_2d = 0x38;
+		else
+			state->reg_2d = 0xbf;
 		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
 		break;
 
@@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	/* Configure Encoder */
-
-	v4l2_dbg(1, debug, sd, "Configuring encoder\n");
-	saa7127_write_inittab(sd, saa7127_init_config_common);
-	saa7127_set_std(sd, V4L2_STD_NTSC);
-	saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
-	saa7127_set_vps(sd, &vbi);
-	saa7127_set_wss(sd, &vbi);
-	saa7127_set_cc(sd, &vbi);
-	saa7127_set_xds(sd, &vbi);
-	if (test_image == 1)
-		/* The Encoder has an internal Colorbar generator */
-		/* This can be used for debugging */
-		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
-	else
-		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
-	saa7127_set_video_enable(sd, 1);
-
 	if (id->driver_data) {	/* Chip type is already known */
 		state->ident = id->driver_data;
 	} else {		/* Needs detection */
@@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client,
 
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
 			client->addr << 1, client->adapter->name);
+
+	v4l2_dbg(1, debug, sd, "Configuring encoder\n");
+	saa7127_write_inittab(sd, saa7127_init_config_common);
+	saa7127_set_std(sd, V4L2_STD_NTSC);
+	saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
+	saa7127_set_vps(sd, &vbi);
+	saa7127_set_wss(sd, &vbi);
+	saa7127_set_cc(sd, &vbi);
+	saa7127_set_xds(sd, &vbi);
+	if (test_image == 1)
+		/* The Encoder has an internal Colorbar generator */
+		/* This can be used for debugging */
+		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
+	else
+		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
+	saa7127_set_video_enable(sd, 1);
+
 	if (state->ident == V4L2_IDENT_SAA7129)
 		saa7127_write_inittab(sd, saa7129_init_config_extra);
 	return 0;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 26194a0ce927c4e414c66c89dbabf29d8a00fdbd..c750d3dd57d20c2f8a858c342ada09b21fd1b1c1 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void)
 
 	list_for_each(list,&saa7134_devlist) {
 		dev = list_entry(list, struct saa7134_dev, devlist);
-		alsa_device_init(dev);
+		if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+			printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+				dev->name, saa7134_boards[dev->board].name);
+		else
+			alsa_device_init(dev);
 	}
 
 	if (dev == NULL)
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index dfbe08a9ad9b8517f4a234ecc86d8c1af52ef98f..99221d726edb373603c6d75789459b3209b03b9b 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -660,6 +660,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
 
 	saa_writel(SAA7134_IRQ1, 0);
 	saa_writel(SAA7134_IRQ2, 0);
+
+	/* Clear any stale IRQ reports */
+	saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
+
 	mutex_init(&dev->lock);
 	spin_lock_init(&dev->slock);
 
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 454ad1dd7507a5f523b8513ef10988cd06d6b81f..88c5e942f751806d414b753234dee9d984fb197a 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -30,7 +30,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 56f0c0eb500facd70b7657f5f05cc8d432a25671..00c6cbe06ab0e047d7132b8cb3f699a3ee4049fe 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	struct tda9875 *t = to_state(sd);
-	int chvol=0, volume, balance, left, right;
+	int chvol = 0, volume = 0, balance = 0, left, right;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3b0b84c2e451524b2465effa64754c5db3b7d4be..78277abb733be27074074e671e9abfaad7ffb169 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -427,6 +427,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
 	const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
 
 	memset(tvee, 0, sizeof(*tvee));
+	tvee->tuner_type = TUNER_ABSENT;
+	tvee->tuner2_type = TUNER_ABSENT;
+
 	done = len = beenhere = 0;
 
 	/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index ac9aa40d09f60ea05f0b613a42d8095b6664e428..8e23aa53c29ac7e06ac54c646fb5a97397a663d0 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	decoder->pdata = client->dev.platform_data;
 	if (!decoder->pdata) {
-		v4l_err(client, "No platform data\n!!");
+		v4l_err(client, "No platform data!!\n");
 		return -ENODEV;
 	}
 	/*
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 4f16effb530fd61f33328e57028f67ec8c39faf4..f4522bb0891666742231012f5cc23d9cd519b35e 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -21,7 +21,6 @@
  */
 
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 4b712f69d1b715c1fddce33e9cadb7f531ccf62d..a5fb74bf2407901052a468b9f24dee8be598f2d6 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -21,7 +21,6 @@
  * 02110-1301, USA.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 9907b9aff2b9228bc9aecb92305c7d4418563d8f..6b66ae4f430f04889768575758f06596262d0ded 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -157,7 +157,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 	struct i2c_msg *pmsg;
 	struct usb_usbvision *usbvision;
 	int i, ret;
-	unsigned char addr;
+	unsigned char addr = 0;
 
 	usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
 
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 2208165aa6f0c27db68994b1f3dacce55912fc26..d2576f6391c06f4c643c96f9b0ffc0051e5fa124 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_ctrl.c  --  USB Video Class driver - Controls
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
@@ -29,7 +28,7 @@
 #define UVC_CTRL_DATA_BACKUP	1
 
 /* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Controls
  */
 
 static struct uvc_control_info uvc_ctrls[] = {
@@ -635,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
 		mask = (1 << bits) - 1;
 	}
 
-	/* Sign-extend the value if needed */
+	/* Sign-extend the value if needed. */
 	if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
 		value |= -(value & (1 << (mapping->size - 1)));
 
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89d8bd10a8521b6c108d219470bdebf7850d6651..b12873265cc56c5c811a6cba514305f8e6534a3d 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_driver.c  --  USB Video Class driver
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -49,7 +48,7 @@ static unsigned int uvc_quirks_param;
 unsigned int uvc_trace_param;
 
 /* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Video formats
  */
 
 static struct uvc_format_desc uvc_fmts[] = {
@@ -474,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
 		/* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
 		 * completely. Observed behaviours range from setting the
-		 * value to 1.1x the actual frame size of hardwiring the
+		 * value to 1.1x the actual frame size to hardwiring the
 		 * 16 low bits to 0. This results in a higher than necessary
 		 * memory usage as well as a wrong image size information. For
 		 * uncompressed formats this can be fixed by computing the
@@ -487,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 		/* Some bogus devices report dwMinFrameInterval equal to
 		 * dwMaxFrameInterval and have dwFrameIntervalStep set to
 		 * zero. Setting all null intervals to 1 fixes the problem and
-		 * some other divisions by zero which could happen.
+		 * some other divisions by zero that could happen.
 		 */
 		for (i = 0; i < n; ++i) {
 			interval = get_unaligned_le32(&buffer[26+4*i]);
@@ -1200,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev)
  * Scan the UVC descriptors to locate a chain starting at an Output Terminal
  * and containing the following units:
  *
- * - a USB Streaming Output Terminal
+ * - one Output Terminal (USB Streaming or Display)
  * - zero or one Processing Unit
  * - zero, one or mode single-input Selector Units
  * - zero or one multiple-input Selector Units, provided all inputs are
  *   connected to input terminals
  * - zero, one or mode single-input Extension Units
- * - one Camera Input Terminal, or one or more External terminals.
+ * - one or more Input Terminals (Camera, External or USB Streaming)
  *
  * A side forward scan is made on each detected entity to check for additional
  * extension units.
@@ -1531,10 +1530,6 @@ static int uvc_register_video(struct uvc_device *dev)
 
 	/* Set the driver data before calling video_register_device, otherwise
 	 * uvc_v4l2_open might race us.
-	 *
-	 * FIXME: usb_set_intfdata hasn't been called so far. Is that a
-	 * 	  problem ? Does any function which could be called here get
-	 * 	  a pointer to the usb_interface ?
 	 */
 	dev->video.vdev = vdev;
 	video_set_drvdata(vdev, &dev->video);
@@ -1569,7 +1564,7 @@ void uvc_delete(struct kref *kref)
 	struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
 	struct list_head *p, *n;
 
-	/* Unregister the video device */
+	/* Unregister the video device. */
 	uvc_unregister_video(dev);
 	usb_put_intf(dev->intf);
 	usb_put_dev(dev->udev);
@@ -1612,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf,
 		uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
 				udev->devpath);
 
-	/* Allocate memory for the device and initialize it */
+	/* Allocate memory for the device and initialize it. */
 	if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 
@@ -1633,14 +1628,14 @@ static int uvc_probe(struct usb_interface *intf,
 			le16_to_cpu(udev->descriptor.idVendor),
 			le16_to_cpu(udev->descriptor.idProduct));
 
-	/* Parse the Video Class control descriptor */
+	/* Parse the Video Class control descriptor. */
 	if (uvc_parse_control(dev) < 0) {
 		uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
 			"descriptors.\n");
 		goto error;
 	}
 
-	uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
+	uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
 		dev->uvc_version >> 8, dev->uvc_version & 0xff,
 		udev->product ? udev->product : "<unnamed>",
 		le16_to_cpu(udev->descriptor.idVendor),
@@ -1653,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf,
 			"linux-uvc-devel mailing list.\n");
 	}
 
-	/* Initialize controls */
+	/* Initialize controls. */
 	if (uvc_ctrl_init_device(dev) < 0)
 		goto error;
 
-	/* Register the video devices */
+	/* Register the video devices. */
 	if (uvc_register_video(dev) < 0)
 		goto error;
 
-	/* Save our data pointer in the interface data */
+	/* Save our data pointer in the interface data. */
 	usb_set_intfdata(intf, dev);
 
-	/* Initialize the interrupt URB */
+	/* Initialize the interrupt URB. */
 	if ((ret = uvc_status_init(dev)) < 0) {
 		uvc_printk(KERN_INFO, "Unable to initialize the status "
 			"endpoint (%d), status interrupt will not be "
@@ -1839,24 +1834,24 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0 },
 	/* Apple Built-In iSight */
-	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
 	  .idVendor		= 0x05ac,
 	  .idProduct		= 0x8501,
-	  .bInterfaceClass      = USB_CLASS_VIDEO,
-	  .bInterfaceSubClass   = 1,
-	  .bInterfaceProtocol   = 0,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
 	  .driver_info 		= UVC_QUIRK_PROBE_MINMAX
 				| UVC_QUIRK_BUILTIN_ISIGHT },
 	/* Genesys Logic USB 2.0 PC Camera */
-	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor             = 0x05e3,
-	  .idProduct            = 0x0505,
-	  .bInterfaceClass      = USB_CLASS_VIDEO,
-	  .bInterfaceSubClass   = 1,
-	  .bInterfaceProtocol   = 0,
-	  .driver_info          = UVC_QUIRK_STREAM_NO_FID },
+	  .idVendor		= 0x05e3,
+	  .idProduct		= 0x0505,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
 	/* MT6227 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 37bdefdbead511ea671190effe1912ee5e4d057b..436f462685a09adb3e959e1f92c5b5f3bb0ae9eb 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -3,6 +3,8 @@
  *
  *	Copyright (C) 2006-2007
  *		Ivan N. Zlatev <contact@i-nz.net>
+ *	Copyright (C) 2008-2009
+ *		Laurent Pinchart <laurent.pinchart@skynet.be>
  *
  *      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
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 42546342e97d08b2f46263df98fbb07f02f18b97..0155752e4a5aea54140c55044a266df1099b8575 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_queue.c  --  USB Video Class driver - Buffers management
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -37,22 +36,22 @@
  * to user space will return -EBUSY.
  *
  * Video buffers are managed using two queues. However, unlike most USB video
- * drivers which use an in queue and an out queue, we use a main queue which
- * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
- * queue which holds empty buffers. This design (copied from video-buf)
- * minimizes locking in interrupt, as only one queue is shared between
- * interrupt and user contexts.
+ * drivers that use an in queue and an out queue, we use a main queue to hold
+ * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
+ * hold empty buffers. This design (copied from video-buf) minimizes locking
+ * in interrupt, as only one queue is shared between interrupt and user
+ * contexts.
  *
  * Use cases
  * ---------
  *
- * Unless stated otherwise, all operations which modify the irq buffers queue
+ * Unless stated otherwise, all operations that modify the irq buffers queue
  * are protected by the irq spinlock.
  *
  * 1. The user queues the buffers, starts streaming and dequeues a buffer.
  *
  *    The buffers are added to the main and irq queues. Both operations are
- *    protected by the queue lock, and the latert is protected by the irq
+ *    protected by the queue lock, and the later is protected by the irq
  *    spinlock as well.
  *
  *    The completion handler fetches a buffer from the irq queue and fills it
@@ -60,7 +59,7 @@
  *    returns immediately.
  *
  *    When the buffer is full, the completion handler removes it from the irq
- *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
+ *    queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
  *    At that point, any process waiting on the buffer will be woken up. If a
  *    process tries to dequeue a buffer after it has been marked ready, the
  *    dequeing will succeed immediately.
@@ -91,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
 /*
  * Allocate the video buffers.
  *
- * Pages are reserved to make sure they will not be swaped, as they will be
- * filled in URB completion handler.
+ * Pages are reserved to make sure they will not be swapped, as they will be
+ * filled in the URB completion handler.
  *
  * Buffers will be individually mapped, so they must all be page aligned.
  */
@@ -210,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
 	__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
 
 done:
-       mutex_unlock(&queue->mutex);
-       return ret;
+	mutex_unlock(&queue->mutex);
+	return ret;
 }
 
 /*
@@ -236,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
 	}
 
 	mutex_lock(&queue->mutex);
-	if (v4l2_buf->index >= queue->count)  {
+	if (v4l2_buf->index >= queue->count) {
 		uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
 		ret = -EINVAL;
 		goto done;
@@ -429,7 +428,7 @@ int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
  * Cancel the video buffers queue.
  *
  * Cancelling the queue marks all buffers on the irq queue as erroneous,
- * wakes them up and remove them from the queue.
+ * wakes them up and removes them from the queue.
  *
  * If the disconnect parameter is set, further calls to uvc_queue_buffer will
  * fail with -ENODEV.
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 5d60b264d59a1d2f7d2a3b41c224023cc5aff40e..c1e4ae27c61388f9c70c529badef2dfc9dd0808d 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_status.c  --  USB Video Class driver - Status endpoint
  *
- *      Copyright (C) 2007-2008
+ *      Copyright (C) 2007-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index fa150fff2c10964e0ea8c2b9deb0ac22a98a96a3..d681519d0c8ae1ffa380352f85819c59ee44450f 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_v4l2.c  --  USB Video Class driver - V4L2 API
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
  * must be grouped (for instance the Red Balance, Blue Balance and Do White
  * Balance V4L2 controls use the White Balance Component UVC control) or
  * otherwise translated. The approach we take here is to use a translation
- * table for the controls which can be mapped directly, and handle the others
+ * table for the controls that can be mapped directly, and handle the others
  * manually.
  */
 static int uvc_v4l2_query_menu(struct uvc_video_device *video,
@@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
 		probe->dwMaxVideoFrameSize =
 			video->streaming->ctrl.dwMaxVideoFrameSize;
 
-	/* Probe the device */
+	/* Probe the device. */
 	if ((ret = uvc_probe_video(video, probe)) < 0)
 		goto done;
 
@@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
  *
  * Each open instance of a UVC device can either be in a privileged or
  * unprivileged state. Only a single instance can be in a privileged state at
- * a given time. Trying to perform an operation which requires privileges will
+ * a given time. Trying to perform an operation that requires privileges will
  * automatically acquire the required privileges if possible, or return -EBUSY
  * otherwise. Privileges are dismissed when closing the instance.
  *
- * Operations which require privileges are:
+ * Operations that require privileges are:
  *
  * - VIDIOC_S_INPUT
  * - VIDIOC_S_PARM
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index e7c31995527f3d520d50283b8246e5cc5a312b6c..9bc4705be78d8ebb893a9dd24d2e6215c344507f 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1,7 +1,7 @@
 /*
  *      uvc_video.c  --  USB Video Class driver - Video handling
  *
- *      Copyright (C) 2005-2008
+ *      Copyright (C) 2005-2009
  *          Laurent Pinchart (laurent.pinchart@skynet.be)
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/usb.h>
@@ -115,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 		ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
 		ret = 0;
 		goto out;
-	} else if (query == GET_DEF && probe == 1) {
+	} else if (query == GET_DEF && probe == 1 && ret != size) {
 		/* Many cameras don't support the GET_DEF request on their
 		 * video probe control. Warn once and return, the caller will
 		 * fall back to GET_CUR.
@@ -160,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 	}
 
 	/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
-	 * Try to get the value from the format and frame descriptor.
+	 * Try to get the value from the format and frame descriptors.
 	 */
 	uvc_fixup_buffer_size(video, ctrl);
 	ret = 0;
@@ -191,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
 	*(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
 	*(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
 	*(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
-	/* Note: Some of the fields below are not required for IN devices (see
-	 * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
-	 * devices is added in the future. */
 	put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
 	put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
 
@@ -400,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 	 *
 	 * Empty buffers (bytesused == 0) don't trigger end of frame detection
 	 * as it doesn't make sense to return an empty buffer. This also
-	 * avoids detecting and of frame conditions at FID toggling if the
+	 * avoids detecting end of frame conditions at FID toggling if the
 	 * previous payload had the EOF bit set.
 	 */
 	if (fid != video->last_fid && buf->buf.bytesused != 0) {
@@ -453,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
 	}
 }
 
+/* Video payload encoding is handled by uvc_video_encode_header() and
+ * uvc_video_encode_data(). Only bulk transfers are currently supported.
+ *
+ * uvc_video_encode_header is called at the start of a payload. It adds header
+ * data to the transfer buffer and returns the header size. As the only known
+ * UVC output device transfers a whole frame in a single payload, the EOF bit
+ * is always set in the header.
+ *
+ * uvc_video_encode_data is called for every URB and copies the data from the
+ * video buffer to the transfer buffer.
+ */
 static int uvc_video_encode_header(struct uvc_video_device *video,
 		struct uvc_buffer *buf, __u8 *data, int len)
 {
@@ -953,7 +960,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
 }
 
 /*
- * Reconfigure the video interface and restart streaming if it was enable
+ * Reconfigure the video interface and restart streaming if it was enabled
  * before suspend.
  *
  * If an error occurs, disable the video queue. This will wake all pending
@@ -985,8 +992,8 @@ int uvc_video_resume(struct uvc_video_device *video)
  */
 
 /*
- * Initialize the UVC video device by retrieving the default format and
- * committing it.
+ * Initialize the UVC video device by switching to alternate setting 0 and
+ * retrieve the default format.
  *
  * Some cameras (namely the Fuji Finepix) set the format and frame
  * indexes to zero. The UVC standard doesn't clearly make this a spec
@@ -1014,7 +1021,7 @@ int uvc_video_init(struct uvc_video_device *video)
 	 */
 	usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
 
-	/* Some webcams don't suport GET_DEF request on the probe control. We
+	/* Some webcams don't suport GET_DEF requests on the probe control. We
 	 * fall back to GET_CUR if GET_DEF fails.
 	 */
 	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index bcf4361dc1bc8ffd543e5f1533d0b85d413da076..027947ea9b6eb497bc1263f07680902d08bec5ba 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -72,149 +72,149 @@ struct uvc_xu_control {
  * UVC constants
  */
 
-#define SC_UNDEFINED                    0x00
-#define SC_VIDEOCONTROL                 0x01
-#define SC_VIDEOSTREAMING               0x02
-#define SC_VIDEO_INTERFACE_COLLECTION   0x03
+#define SC_UNDEFINED			0x00
+#define SC_VIDEOCONTROL			0x01
+#define SC_VIDEOSTREAMING		0x02
+#define SC_VIDEO_INTERFACE_COLLECTION	0x03
 
-#define PC_PROTOCOL_UNDEFINED           0x00
+#define PC_PROTOCOL_UNDEFINED		0x00
 
-#define CS_UNDEFINED                    0x20
-#define CS_DEVICE                       0x21
-#define CS_CONFIGURATION                0x22
-#define CS_STRING                       0x23
-#define CS_INTERFACE                    0x24
-#define CS_ENDPOINT                     0x25
+#define CS_UNDEFINED			0x20
+#define CS_DEVICE			0x21
+#define CS_CONFIGURATION		0x22
+#define CS_STRING			0x23
+#define CS_INTERFACE			0x24
+#define CS_ENDPOINT			0x25
 
 /* VideoControl class specific interface descriptor */
-#define VC_DESCRIPTOR_UNDEFINED         0x00
-#define VC_HEADER                       0x01
-#define VC_INPUT_TERMINAL               0x02
-#define VC_OUTPUT_TERMINAL              0x03
-#define VC_SELECTOR_UNIT                0x04
-#define VC_PROCESSING_UNIT              0x05
-#define VC_EXTENSION_UNIT               0x06
+#define VC_DESCRIPTOR_UNDEFINED		0x00
+#define VC_HEADER			0x01
+#define VC_INPUT_TERMINAL		0x02
+#define VC_OUTPUT_TERMINAL		0x03
+#define VC_SELECTOR_UNIT		0x04
+#define VC_PROCESSING_UNIT		0x05
+#define VC_EXTENSION_UNIT		0x06
 
 /* VideoStreaming class specific interface descriptor */
-#define VS_UNDEFINED                    0x00
-#define VS_INPUT_HEADER                 0x01
-#define VS_OUTPUT_HEADER                0x02
-#define VS_STILL_IMAGE_FRAME            0x03
-#define VS_FORMAT_UNCOMPRESSED          0x04
-#define VS_FRAME_UNCOMPRESSED           0x05
-#define VS_FORMAT_MJPEG                 0x06
-#define VS_FRAME_MJPEG                  0x07
-#define VS_FORMAT_MPEG2TS               0x0a
-#define VS_FORMAT_DV                    0x0c
-#define VS_COLORFORMAT                  0x0d
-#define VS_FORMAT_FRAME_BASED           0x10
-#define VS_FRAME_FRAME_BASED            0x11
-#define VS_FORMAT_STREAM_BASED          0x12
+#define VS_UNDEFINED			0x00
+#define VS_INPUT_HEADER			0x01
+#define VS_OUTPUT_HEADER		0x02
+#define VS_STILL_IMAGE_FRAME		0x03
+#define VS_FORMAT_UNCOMPRESSED		0x04
+#define VS_FRAME_UNCOMPRESSED		0x05
+#define VS_FORMAT_MJPEG			0x06
+#define VS_FRAME_MJPEG			0x07
+#define VS_FORMAT_MPEG2TS		0x0a
+#define VS_FORMAT_DV			0x0c
+#define VS_COLORFORMAT			0x0d
+#define VS_FORMAT_FRAME_BASED		0x10
+#define VS_FRAME_FRAME_BASED		0x11
+#define VS_FORMAT_STREAM_BASED		0x12
 
 /* Endpoint type */
-#define EP_UNDEFINED                    0x00
-#define EP_GENERAL                      0x01
-#define EP_ENDPOINT                     0x02
-#define EP_INTERRUPT                    0x03
+#define EP_UNDEFINED			0x00
+#define EP_GENERAL			0x01
+#define EP_ENDPOINT			0x02
+#define EP_INTERRUPT			0x03
 
 /* Request codes */
-#define RC_UNDEFINED                    0x00
-#define SET_CUR                         0x01
-#define GET_CUR                         0x81
-#define GET_MIN                         0x82
-#define GET_MAX                         0x83
-#define GET_RES                         0x84
-#define GET_LEN                         0x85
-#define GET_INFO                        0x86
-#define GET_DEF                         0x87
+#define RC_UNDEFINED			0x00
+#define SET_CUR				0x01
+#define GET_CUR				0x81
+#define GET_MIN				0x82
+#define GET_MAX				0x83
+#define GET_RES				0x84
+#define GET_LEN				0x85
+#define GET_INFO			0x86
+#define GET_DEF				0x87
 
 /* VideoControl interface controls */
-#define VC_CONTROL_UNDEFINED            0x00
-#define VC_VIDEO_POWER_MODE_CONTROL     0x01
-#define VC_REQUEST_ERROR_CODE_CONTROL   0x02
+#define VC_CONTROL_UNDEFINED		0x00
+#define VC_VIDEO_POWER_MODE_CONTROL	0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL	0x02
 
 /* Terminal controls */
-#define TE_CONTROL_UNDEFINED            0x00
+#define TE_CONTROL_UNDEFINED		0x00
 
 /* Selector Unit controls */
-#define SU_CONTROL_UNDEFINED            0x00
-#define SU_INPUT_SELECT_CONTROL         0x01
+#define SU_CONTROL_UNDEFINED		0x00
+#define SU_INPUT_SELECT_CONTROL		0x01
 
 /* Camera Terminal controls */
-#define CT_CONTROL_UNDEFINED            		0x00
-#define CT_SCANNING_MODE_CONTROL        		0x01
-#define CT_AE_MODE_CONTROL              		0x02
-#define CT_AE_PRIORITY_CONTROL          		0x03
-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL               0x04
-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL               0x05
-#define CT_FOCUS_ABSOLUTE_CONTROL       		0x06
-#define CT_FOCUS_RELATIVE_CONTROL       		0x07
-#define CT_FOCUS_AUTO_CONTROL           		0x08
-#define CT_IRIS_ABSOLUTE_CONTROL        		0x09
-#define CT_IRIS_RELATIVE_CONTROL        		0x0a
-#define CT_ZOOM_ABSOLUTE_CONTROL        		0x0b
-#define CT_ZOOM_RELATIVE_CONTROL        		0x0c
-#define CT_PANTILT_ABSOLUTE_CONTROL     		0x0d
-#define CT_PANTILT_RELATIVE_CONTROL     		0x0e
-#define CT_ROLL_ABSOLUTE_CONTROL        		0x0f
-#define CT_ROLL_RELATIVE_CONTROL        		0x10
-#define CT_PRIVACY_CONTROL              		0x11
+#define CT_CONTROL_UNDEFINED				0x00
+#define CT_SCANNING_MODE_CONTROL			0x01
+#define CT_AE_MODE_CONTROL				0x02
+#define CT_AE_PRIORITY_CONTROL				0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL		0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL		0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL			0x06
+#define CT_FOCUS_RELATIVE_CONTROL			0x07
+#define CT_FOCUS_AUTO_CONTROL				0x08
+#define CT_IRIS_ABSOLUTE_CONTROL			0x09
+#define CT_IRIS_RELATIVE_CONTROL			0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL			0x0b
+#define CT_ZOOM_RELATIVE_CONTROL			0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL			0x0d
+#define CT_PANTILT_RELATIVE_CONTROL			0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL			0x0f
+#define CT_ROLL_RELATIVE_CONTROL			0x10
+#define CT_PRIVACY_CONTROL				0x11
 
 /* Processing Unit controls */
-#define PU_CONTROL_UNDEFINED            		0x00
-#define PU_BACKLIGHT_COMPENSATION_CONTROL               0x01
-#define PU_BRIGHTNESS_CONTROL           		0x02
-#define PU_CONTRAST_CONTROL             		0x03
-#define PU_GAIN_CONTROL                 		0x04
-#define PU_POWER_LINE_FREQUENCY_CONTROL 		0x05
-#define PU_HUE_CONTROL                  		0x06
-#define PU_SATURATION_CONTROL           		0x07
-#define PU_SHARPNESS_CONTROL            		0x08
-#define PU_GAMMA_CONTROL                		0x09
-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL            0x0a
-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL       0x0b
-#define PU_WHITE_BALANCE_COMPONENT_CONTROL              0x0c
-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL         0x0d
-#define PU_DIGITAL_MULTIPLIER_CONTROL   		0x0e
-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL             0x0f
-#define PU_HUE_AUTO_CONTROL             		0x10
-#define PU_ANALOG_VIDEO_STANDARD_CONTROL                0x11
-#define PU_ANALOG_LOCK_STATUS_CONTROL   		0x12
+#define PU_CONTROL_UNDEFINED				0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL		0x01
+#define PU_BRIGHTNESS_CONTROL				0x02
+#define PU_CONTRAST_CONTROL				0x03
+#define PU_GAIN_CONTROL					0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL			0x05
+#define PU_HUE_CONTROL					0x06
+#define PU_SATURATION_CONTROL				0x07
+#define PU_SHARPNESS_CONTROL				0x08
+#define PU_GAMMA_CONTROL				0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL		0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL	0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL		0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL		0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL			0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL		0x0f
+#define PU_HUE_AUTO_CONTROL				0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL		0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL			0x12
 
 #define LXU_MOTOR_PANTILT_RELATIVE_CONTROL		0x01
 #define LXU_MOTOR_PANTILT_RESET_CONTROL			0x02
 #define LXU_MOTOR_FOCUS_MOTOR_CONTROL			0x03
 
 /* VideoStreaming interface controls */
-#define VS_CONTROL_UNDEFINED            0x00
-#define VS_PROBE_CONTROL                0x01
-#define VS_COMMIT_CONTROL               0x02
-#define VS_STILL_PROBE_CONTROL          0x03
-#define VS_STILL_COMMIT_CONTROL         0x04
-#define VS_STILL_IMAGE_TRIGGER_CONTROL  0x05
-#define VS_STREAM_ERROR_CODE_CONTROL    0x06
-#define VS_GENERATE_KEY_FRAME_CONTROL   0x07
-#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
-#define VS_SYNC_DELAY_CONTROL           0x09
-
-#define TT_VENDOR_SPECIFIC              0x0100
-#define TT_STREAMING                    0x0101
+#define VS_CONTROL_UNDEFINED		0x00
+#define VS_PROBE_CONTROL		0x01
+#define VS_COMMIT_CONTROL		0x02
+#define VS_STILL_PROBE_CONTROL		0x03
+#define VS_STILL_COMMIT_CONTROL		0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL	0x05
+#define VS_STREAM_ERROR_CODE_CONTROL	0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL	0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL	0x08
+#define VS_SYNC_DELAY_CONTROL		0x09
+
+#define TT_VENDOR_SPECIFIC		0x0100
+#define TT_STREAMING			0x0101
 
 /* Input Terminal types */
-#define ITT_VENDOR_SPECIFIC             0x0200
-#define ITT_CAMERA                      0x0201
-#define ITT_MEDIA_TRANSPORT_INPUT       0x0202
+#define ITT_VENDOR_SPECIFIC		0x0200
+#define ITT_CAMERA			0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT	0x0202
 
 /* Output Terminal types */
-#define OTT_VENDOR_SPECIFIC             0x0300
-#define OTT_DISPLAY                     0x0301
-#define OTT_MEDIA_TRANSPORT_OUTPUT      0x0302
+#define OTT_VENDOR_SPECIFIC		0x0300
+#define OTT_DISPLAY			0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT	0x0302
 
 /* External Terminal types */
-#define EXTERNAL_VENDOR_SPECIFIC        0x0400
-#define COMPOSITE_CONNECTOR             0x0401
-#define SVIDEO_CONNECTOR                0x0402
-#define COMPONENT_CONNECTOR             0x0403
+#define EXTERNAL_VENDOR_SPECIFIC	0x0400
+#define COMPOSITE_CONNECTOR		0x0401
+#define SVIDEO_CONNECTOR		0x0402
+#define COMPONENT_CONNECTOR		0x0403
 
 #define UVC_TERM_INPUT			0x0000
 #define UVC_TERM_OUTPUT			0x8000
@@ -541,11 +541,11 @@ struct uvc_streaming {
 };
 
 enum uvc_buffer_state {
-	UVC_BUF_STATE_IDLE       = 0,
-	UVC_BUF_STATE_QUEUED     = 1,
-	UVC_BUF_STATE_ACTIVE     = 2,
-	UVC_BUF_STATE_DONE       = 3,
-	UVC_BUF_STATE_ERROR      = 4,
+	UVC_BUF_STATE_IDLE	= 0,
+	UVC_BUF_STATE_QUEUED	= 1,
+	UVC_BUF_STATE_ACTIVE	= 2,
+	UVC_BUF_STATE_DONE	= 3,
+	UVC_BUF_STATE_ERROR	= 4,
 };
 
 struct uvc_buffer {
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index fbe9cc0d433a29cf16a33d89a55a001596ad0c5e..21208805ea9bb67991de26a14738cf2b486247d2 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -28,13 +28,13 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
 {
 	switch (cmd) {
 	case VIDIOC_QUERYCTRL:
-		return v4l2_subdev_call(sd, core, querymenu, arg);
+		return v4l2_subdev_call(sd, core, queryctrl, arg);
 	case VIDIOC_G_CTRL:
 		return v4l2_subdev_call(sd, core, g_ctrl, arg);
 	case VIDIOC_S_CTRL:
 		return v4l2_subdev_call(sd, core, s_ctrl, arg);
 	case VIDIOC_QUERYMENU:
-		return v4l2_subdev_call(sd, core, queryctrl, arg);
+		return v4l2_subdev_call(sd, core, querymenu, arg);
 	case VIDIOC_LOG_STATUS:
 		return v4l2_subdev_call(sd, core, log_status);
 	case VIDIOC_DBG_G_CHIP_IDENT:
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index 46b7ad477ceb5caece92b5e0cab3d601895bf2ce..e873a916250f4dbfbca98370413eb064a9c3f81b 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -349,7 +349,6 @@ struct card_info {
 	u16 i2c_decoder, i2c_encoder;			/* I2C types */
 	u16 video_vfe, video_codec;			/* videocodec types */
 	u16 audio_chip;					/* audio type */
-	u16 vendor_id, device_id;	/* subsystem vendor/device ID */
 
 	int inputs;		/* number of video inputs */
 	struct input {
@@ -401,7 +400,6 @@ struct zoran {
 	char name[32];		/* name of this device */
 	struct pci_dev *pci_dev;	/* PCI device */
 	unsigned char revision;	/* revision of zr36057 */
-	unsigned int zr36057_adr;	/* bus address of IO mem returned by PCI BIOS */
 	unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
 
 	spinlock_t spinlock;	/* Spinlock */
@@ -490,16 +488,10 @@ struct zoran {
 	wait_queue_head_t test_q;
 };
 
-/*The following should be done in more portable way. It depends on define
-  of _ALPHA_BUZ in the Makefile.*/
-
-#ifdef _ALPHA_BUZ
-#define btwrite(dat,adr)    writel((dat), zr->zr36057_adr+(adr))
-#define btread(adr)         readl(zr->zr36057_adr+(adr))
-#else
+/* There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite.  */
 #define btwrite(dat,adr)    writel((dat), zr->zr36057_mem+(adr))
 #define btread(adr)         readl(zr->zr36057_mem+(adr))
-#endif
 
 #define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
 #define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 05f39195372e00def2749ee47428db426f63c7a1..5d2f090aa0f82c12aa3adec4daed69bffea4d63a 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -61,17 +61,17 @@
 
 extern const struct zoran_format zoran_formats[];
 
-static int card[BUZ_MAX] = { -1, -1, -1, -1 };
+static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "The type of card");
+MODULE_PARM_DESC(card, "Card type");
 
-static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(encoder, int, NULL, 0444);
-MODULE_PARM_DESC(encoder, "i2c TV encoder");
+MODULE_PARM_DESC(encoder, "Video encoder chip");
 
-static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(decoder, int, NULL, 0444);
-MODULE_PARM_DESC(decoder, "i2c TV decoder");
+MODULE_PARM_DESC(decoder, "Video decoder chip");
 
 /*
    The video mem address of the video card.
@@ -104,9 +104,9 @@ module_param(default_norm, int, 0444);
 MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
 
 /* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
+static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
 module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
 
 /*
    Number and size of grab buffers for Video 4 Linux
@@ -153,9 +153,21 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
 MODULE_AUTHOR("Serguei Miridonov");
 MODULE_LICENSE("GPL");
 
+#define ZR_DEVICE(subven, subdev, data)	{ \
+	.vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
+	.subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+
+static struct pci_device_id zr36067_pci_tbl[] = {
+	ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
+	ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
+	ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
+	ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
+	ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
+	{0}
+};
+MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
 
-int zoran_num;			/* number of Buzs in use */
-struct zoran *zoran[BUZ_MAX];
+static unsigned int zoran_num;		/* number of cards found */
 
 /* videocodec bus functions ZR36060 */
 static u32
@@ -472,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = DC10plus,
 		.name = "DC10plus",
-		.vendor_id = PCI_VENDOR_ID_MIRO,
-		.device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
 		.i2c_decoder = I2C_DRIVERID_SAA7110,
 		.i2c_encoder = I2C_DRIVERID_ADV7175,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -531,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = DC30plus,
 		.name = "DC30plus",
-		.vendor_id = PCI_VENDOR_ID_MIRO,
-		.device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
 		.i2c_decoder = I2C_DRIVERID_VPX3220,
 		.i2c_encoder = I2C_DRIVERID_ADV7175,
 		.video_codec = CODEC_TYPE_ZR36050,
@@ -589,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = LML33R10,
 		.name = "LML33R10",
-		.vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
-		.device_id = PCI_DEVICE_ID_LML_33R10,
 		.i2c_decoder = I2C_DRIVERID_SAA7114,
 		.i2c_encoder = I2C_DRIVERID_ADV7170,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -618,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 	}, {
 		.type = BUZ,
 		.name = "Buz",
-		.vendor_id = PCI_VENDOR_ID_IOMEGA,
-		.device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
 		.i2c_decoder = I2C_DRIVERID_SAA7111A,
 		.i2c_encoder = I2C_DRIVERID_SAA7185B,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -649,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
 		.name = "6-Eyes",
 		/* AverMedia chose not to brand the 6-Eyes. Thus it
 		   can't be autodetected, and requires card=x. */
-		.vendor_id = -1,
-		.device_id = -1,
 		.i2c_decoder = I2C_DRIVERID_KS0127,
 		.i2c_encoder = I2C_DRIVERID_BT866,
 		.video_codec = CODEC_TYPE_ZR36060,
@@ -1138,7 +1140,8 @@ zr36057_init (struct zoran *zr)
 	strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
 	err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
 	if (err < 0)
-		goto exit_unregister;
+		goto exit_free;
+	video_set_drvdata(zr->video_dev, zr);
 
 	zoran_init_hardware(zr);
 	if (zr36067_debug > 2)
@@ -1153,19 +1156,19 @@ zr36057_init (struct zoran *zr)
 	zr->initialized = 1;
 	return 0;
 
-exit_unregister:
-	zoran_unregister_i2c(zr);
 exit_free:
 	kfree(zr->stat_com);
 	kfree(zr->video_dev);
 	return err;
 }
 
-static void
-zoran_release (struct zoran *zr)
+static void __devexit zoran_remove(struct pci_dev *pdev)
 {
+	struct zoran *zr = pci_get_drvdata(pdev);
+
 	if (!zr->initialized)
 		goto exit_free;
+
 	/* unregister videocodec bus */
 	if (zr->codec) {
 		struct videocodec_master *master = zr->codec->master_data;
@@ -1194,6 +1197,7 @@ zoran_release (struct zoran *zr)
 	pci_disable_device(zr->pci_dev);
 	video_unregister_device(zr->video_dev);
 exit_free:
+	pci_set_drvdata(pdev, NULL);
 	kfree(zr);
 }
 
@@ -1256,338 +1260,329 @@ zoran_setup_videocodec (struct zoran *zr,
  *   Scan for a Buz card (actually for the PCI controller ZR36057),
  *   request the irq and map the io memory
  */
-static int __devinit
-find_zr36057 (void)
+static int __devinit zoran_probe(struct pci_dev *pdev,
+				 const struct pci_device_id *ent)
 {
 	unsigned char latency, need_latency;
 	struct zoran *zr;
-	struct pci_dev *dev = NULL;
 	int result;
 	struct videocodec_master *master_vfe = NULL;
 	struct videocodec_master *master_codec = NULL;
 	int card_num;
 	char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+	unsigned int nr;
 
-	zoran_num = 0;
-	while (zoran_num < BUZ_MAX &&
-	       (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
-		card_num = card[zoran_num];
-		zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
-		if (!zr) {
-			dprintk(1,
-				KERN_ERR
-				"%s: find_zr36057() - kzalloc failed\n",
-				ZORAN_NAME);
-			continue;
-		}
-		zr->pci_dev = dev;
-		//zr->zr36057_mem = NULL;
-		zr->id = zoran_num;
-		snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
-		spin_lock_init(&zr->spinlock);
-		mutex_init(&zr->resource_lock);
-		if (pci_enable_device(dev))
-			goto zr_free_mem;
-		zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
-		pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
-				     &zr->revision);
-		if (zr->revision < 2) {
-			dprintk(1,
-				KERN_INFO
-				"%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
-				ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
-				zr->zr36057_adr);
 
-			if (card_num == -1) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_mem;
-			}
-		} else {
-			int i;
-			unsigned short ss_vendor, ss_device;
+	nr = zoran_num++;
+	if (nr >= BUZ_MAX) {
+		dprintk(1,
+			KERN_ERR
+			"%s: driver limited to %d card(s) maximum\n",
+			ZORAN_NAME, BUZ_MAX);
+		return -ENOENT;
+	}
 
-			ss_vendor = zr->pci_dev->subsystem_vendor;
-			ss_device = zr->pci_dev->subsystem_device;
+	zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+	if (!zr) {
+		dprintk(1,
+			KERN_ERR
+			"%s: find_zr36057() - kzalloc failed\n",
+			ZORAN_NAME);
+		return -ENOMEM;
+	}
+	zr->pci_dev = pdev;
+	zr->id = nr;
+	snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
+	spin_lock_init(&zr->spinlock);
+	mutex_init(&zr->resource_lock);
+	if (pci_enable_device(pdev))
+		goto zr_free_mem;
+	pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+
+	dprintk(1,
+		KERN_INFO
+		"%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
+		ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
+		zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
+	if (zr->revision >= 2) {
+		dprintk(1,
+			KERN_INFO
+			"%s: Subsystem vendor=0x%04x id=0x%04x\n",
+			ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
+			zr->pci_dev->subsystem_device);
+	}
+
+	/* Use auto-detected card type? */
+	if (card[nr] == -1) {
+		if (zr->revision < 2) {
 			dprintk(1,
-				KERN_INFO
-				"%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
-				ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
-				zr->zr36057_adr);
+				KERN_ERR
+				"%s: No card type specified, please use the card=X module parameter\n",
+				ZR_DEVNAME(zr));
 			dprintk(1,
-				KERN_INFO
-				"%s: subsystem vendor=0x%04x id=0x%04x\n",
-				ZR_DEVNAME(zr), ss_vendor, ss_device);
-			if (card_num == -1) {
-				dprintk(3,
-					KERN_DEBUG
-					"%s: find_zr36057() - trying to autodetect card type\n",
-					ZR_DEVNAME(zr));
-				for (i=0;i<NUM_CARDS;i++) {
-					if (ss_vendor == zoran_cards[i].vendor_id &&
-					    ss_device == zoran_cards[i].device_id) {
-						dprintk(3,
-							KERN_DEBUG
-							"%s: find_zr36057() - card %s detected\n",
-							ZR_DEVNAME(zr),
-							zoran_cards[i].name);
-						card_num = i;
-						break;
-					}
-				}
-				if (i == NUM_CARDS) {
-					dprintk(1,
-						KERN_ERR
-						"%s: find_zr36057() - unknown card\n",
-						ZR_DEVNAME(zr));
-					goto zr_free_mem;
-				}
-			}
-		}
-
-		if (card_num < 0 || card_num >= NUM_CARDS) {
-			dprintk(2,
 				KERN_ERR
-				"%s: find_zr36057() - invalid cardnum %d\n",
-				ZR_DEVNAME(zr), card_num);
+				"%s: It is not possible to auto-detect ZR36057 based cards\n",
+				ZR_DEVNAME(zr));
 			goto zr_free_mem;
 		}
 
-		/* even though we make this a non pointer and thus
-		 * theoretically allow for making changes to this struct
-		 * on a per-individual card basis at runtime, this is
-		 * strongly discouraged. This structure is intended to
-		 * keep general card information, no settings or anything */
-		zr->card = zoran_cards[card_num];
-		snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
-			 "%s[%u]", zr->card.name, zr->id);
-
-		zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
-		if (!zr->zr36057_mem) {
+		card_num = ent->driver_data;
+		if (card_num >= NUM_CARDS) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - ioremap failed\n",
+				"%s: Unknown card, try specifying card=X module parameter\n",
 				ZR_DEVNAME(zr));
 			goto zr_free_mem;
 		}
-
-		result = request_irq(zr->pci_dev->irq,
-				     zoran_irq,
-				     IRQF_SHARED | IRQF_DISABLED,
-				     ZR_DEVNAME(zr),
-				     (void *) zr);
-		if (result < 0) {
-			if (result == -EINVAL) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - bad irq number or handler\n",
-					ZR_DEVNAME(zr));
-			} else if (result == -EBUSY) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
-					ZR_DEVNAME(zr), zr->pci_dev->irq);
-			} else {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - can't assign irq, error code %d\n",
-					ZR_DEVNAME(zr), result);
-			}
-			goto zr_unmap;
-		}
-
-		/* set PCI latency timer */
-		pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
-				     &latency);
-		need_latency = zr->revision > 1 ? 32 : 48;
-		if (latency != need_latency) {
-			dprintk(2,
-				KERN_INFO
-				"%s: Changing PCI latency from %d to %d.\n",
-				ZR_DEVNAME(zr), latency, need_latency);
-			pci_write_config_byte(zr->pci_dev,
-					      PCI_LATENCY_TIMER,
-					      need_latency);
+		dprintk(3,
+			KERN_DEBUG
+			"%s: %s() - card %s detected\n",
+			ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
+	} else {
+		card_num = card[nr];
+		if (card_num >= NUM_CARDS || card_num < 0) {
+			dprintk(1,
+				KERN_ERR
+				"%s: User specified card type %d out of range (0 .. %d)\n",
+				ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
+			goto zr_free_mem;
 		}
+	}
 
-		zr36057_restart(zr);
-		/* i2c */
-		dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
-			ZR_DEVNAME(zr));
+	/* even though we make this a non pointer and thus
+	 * theoretically allow for making changes to this struct
+	 * on a per-individual card basis at runtime, this is
+	 * strongly discouraged. This structure is intended to
+	 * keep general card information, no settings or anything */
+	zr->card = zoran_cards[card_num];
+	snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
+		 "%s[%u]", zr->card.name, zr->id);
+
+	zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
+	if (!zr->zr36057_mem) {
+		dprintk(1,
+			KERN_ERR
+			"%s: %s() - ioremap failed\n",
+			ZR_DEVNAME(zr), __func__);
+		goto zr_free_mem;
+	}
 
-		/* i2c decoder */
-		if (decoder[zr->id] != -1) {
-			i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
-			zr->card.i2c_decoder = decoder[zr->id];
-		} else if (zr->card.i2c_decoder != 0) {
-			i2c_dec_name =
-				i2cid_to_modulename(zr->card.i2c_decoder);
+	result = request_irq(zr->pci_dev->irq, zoran_irq,
+			     IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
+	if (result < 0) {
+		if (result == -EINVAL) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - bad irq number or handler\n",
+				ZR_DEVNAME(zr));
+		} else if (result == -EBUSY) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
+				ZR_DEVNAME(zr), zr->pci_dev->irq);
 		} else {
-			i2c_dec_name = NULL;
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - can't assign irq, error code %d\n",
+				ZR_DEVNAME(zr), result);
 		}
+		goto zr_unmap;
+	}
 
-		if (i2c_dec_name) {
-			if ((result = request_module(i2c_dec_name)) < 0) {
-				dprintk(1,
-					KERN_ERR
-					"%s: failed to load module %s: %d\n",
-					ZR_DEVNAME(zr), i2c_dec_name, result);
-			}
-		}
+	/* set PCI latency timer */
+	pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+			     &latency);
+	need_latency = zr->revision > 1 ? 32 : 48;
+	if (latency != need_latency) {
+		dprintk(2,
+			KERN_INFO
+			"%s: Changing PCI latency from %d to %d\n",
+			ZR_DEVNAME(zr), latency, need_latency);
+		pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+				      need_latency);
+	}
 
-		/* i2c encoder */
-		if (encoder[zr->id] != -1) {
-			i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
-			zr->card.i2c_encoder = encoder[zr->id];
-		} else if (zr->card.i2c_encoder != 0) {
-			i2c_enc_name =
-				i2cid_to_modulename(zr->card.i2c_encoder);
-		} else {
-			i2c_enc_name = NULL;
-		}
+	zr36057_restart(zr);
+	/* i2c */
+	dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
+		ZR_DEVNAME(zr));
+
+	/* i2c decoder */
+	if (decoder[zr->id] != -1) {
+		i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
+		zr->card.i2c_decoder = decoder[zr->id];
+	} else if (zr->card.i2c_decoder != 0) {
+		i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
+	} else {
+		i2c_dec_name = NULL;
+	}
 
-		if (i2c_enc_name) {
-			if ((result = request_module(i2c_enc_name)) < 0) {
-				dprintk(1,
-					KERN_ERR
-					"%s: failed to load module %s: %d\n",
-					ZR_DEVNAME(zr), i2c_enc_name, result);
-			}
+	if (i2c_dec_name) {
+		result = request_module(i2c_dec_name);
+		if (result < 0) {
+			dprintk(1,
+				KERN_ERR
+				"%s: failed to load module %s: %d\n",
+				ZR_DEVNAME(zr), i2c_dec_name, result);
 		}
+	}
+
+	/* i2c encoder */
+	if (encoder[zr->id] != -1) {
+		i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
+		zr->card.i2c_encoder = encoder[zr->id];
+	} else if (zr->card.i2c_encoder != 0) {
+		i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
+	} else {
+		i2c_enc_name = NULL;
+	}
 
-		if (zoran_register_i2c(zr) < 0) {
+	if (i2c_enc_name) {
+		result = request_module(i2c_enc_name);
+		if (result < 0) {
 			dprintk(1,
 				KERN_ERR
-				"%s: find_zr36057() - can't initialize i2c bus\n",
-				ZR_DEVNAME(zr));
-			goto zr_free_irq;
+				"%s: failed to load module %s: %d\n",
+				ZR_DEVNAME(zr), i2c_enc_name, result);
 		}
+	}
 
-		dprintk(2,
-			KERN_INFO "%s: Initializing videocodec bus...\n",
+	if (zoran_register_i2c(zr) < 0) {
+		dprintk(1,
+			KERN_ERR
+			"%s: find_zr36057() - can't initialize i2c bus\n",
 			ZR_DEVNAME(zr));
+		goto zr_free_irq;
+	}
 
-		if (zr->card.video_codec != 0 &&
-		    (codec_name =
-		     codecid_to_modulename(zr->card.video_codec)) != NULL) {
-			if ((result = request_module(codec_name)) < 0) {
+	dprintk(2,
+		KERN_INFO "%s: Initializing videocodec bus...\n",
+		ZR_DEVNAME(zr));
+
+	if (zr->card.video_codec) {
+		codec_name = codecid_to_modulename(zr->card.video_codec);
+		if (codec_name) {
+			result = request_module(codec_name);
+			if (result) {
 				dprintk(1,
 					KERN_ERR
 					"%s: failed to load modules %s: %d\n",
 					ZR_DEVNAME(zr), codec_name, result);
 			}
 		}
-		if (zr->card.video_vfe != 0 &&
-		    (vfe_name =
-		     codecid_to_modulename(zr->card.video_vfe)) != NULL) {
-			if ((result = request_module(vfe_name)) < 0) {
+	}
+	if (zr->card.video_vfe) {
+		vfe_name = codecid_to_modulename(zr->card.video_vfe);
+		if (vfe_name) {
+			result = request_module(vfe_name);
+			if (result < 0) {
 				dprintk(1,
 					KERN_ERR
 					"%s: failed to load modules %s: %d\n",
 					ZR_DEVNAME(zr), vfe_name, result);
 			}
 		}
+	}
 
-		/* reset JPEG codec */
-		jpeg_codec_sleep(zr, 1);
-		jpeg_codec_reset(zr);
-		/* video bus enabled */
-		/* display codec revision */
-		if (zr->card.video_codec != 0) {
-			master_codec = zoran_setup_videocodec(zr,
-							      zr->card.video_codec);
-			if (!master_codec)
-				goto zr_unreg_i2c;
-			zr->codec = videocodec_attach(master_codec);
-			if (!zr->codec) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no codec found\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_codec;
-			}
-			if (zr->codec->type != zr->card.video_codec) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - wrong codec\n",
-					ZR_DEVNAME(zr));
-				goto zr_detach_codec;
-			}
+	/* reset JPEG codec */
+	jpeg_codec_sleep(zr, 1);
+	jpeg_codec_reset(zr);
+	/* video bus enabled */
+	/* display codec revision */
+	if (zr->card.video_codec != 0) {
+		master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
+		if (!master_codec)
+			goto zr_unreg_i2c;
+		zr->codec = videocodec_attach(master_codec);
+		if (!zr->codec) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - no codec found\n",
+				ZR_DEVNAME(zr));
+			goto zr_free_codec;
 		}
-		if (zr->card.video_vfe != 0) {
-			master_vfe = zoran_setup_videocodec(zr,
-							    zr->card.video_vfe);
-			if (!master_vfe)
-				goto zr_detach_codec;
-			zr->vfe = videocodec_attach(master_vfe);
-			if (!zr->vfe) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() - no VFE found\n",
-					ZR_DEVNAME(zr));
-				goto zr_free_vfe;
-			}
-			if (zr->vfe->type != zr->card.video_vfe) {
-				dprintk(1,
-					KERN_ERR
-					"%s: find_zr36057() = wrong VFE\n",
-					ZR_DEVNAME(zr));
-				goto zr_detach_vfe;
-			}
+		if (zr->codec->type != zr->card.video_codec) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - wrong codec\n",
+				ZR_DEVNAME(zr));
+			goto zr_detach_codec;
+		}
+	}
+	if (zr->card.video_vfe != 0) {
+		master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
+		if (!master_vfe)
+			goto zr_detach_codec;
+		zr->vfe = videocodec_attach(master_vfe);
+		if (!zr->vfe) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() - no VFE found\n",
+				ZR_DEVNAME(zr));
+			goto zr_free_vfe;
+		}
+		if (zr->vfe->type != zr->card.video_vfe) {
+			dprintk(1,
+				KERN_ERR
+				"%s: find_zr36057() = wrong VFE\n",
+				ZR_DEVNAME(zr));
+			goto zr_detach_vfe;
 		}
-		/* Success so keep the pci_dev referenced */
-		pci_dev_get(zr->pci_dev);
-		zoran[zoran_num++] = zr;
-		continue;
-
-		// Init errors
-	      zr_detach_vfe:
-		videocodec_detach(zr->vfe);
-	      zr_free_vfe:
-		kfree(master_vfe);
-	      zr_detach_codec:
-		videocodec_detach(zr->codec);
-	      zr_free_codec:
-		kfree(master_codec);
-	      zr_unreg_i2c:
-		zoran_unregister_i2c(zr);
-	      zr_free_irq:
-		btwrite(0, ZR36057_SPGPPCR);
-		free_irq(zr->pci_dev->irq, zr);
-	      zr_unmap:
-		iounmap(zr->zr36057_mem);
-	      zr_free_mem:
-		kfree(zr);
-		continue;
 	}
-	if (dev)	/* Clean up ref count on early exit */
-		pci_dev_put(dev);
 
-	if (zoran_num == 0) {
-		dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
+	/* take care of Natoma chipset and a revision 1 zr36057 */
+	if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
+		zr->jpg_buffers.need_contiguous = 1;
+		dprintk(1,
+			KERN_INFO
+			"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
+			ZR_DEVNAME(zr));
 	}
-	return zoran_num;
+
+	if (zr36057_init(zr) < 0)
+		goto zr_detach_vfe;
+
+	zoran_proc_init(zr);
+
+	pci_set_drvdata(pdev, zr);
+
+	return 0;
+
+zr_detach_vfe:
+	videocodec_detach(zr->vfe);
+zr_free_vfe:
+	kfree(master_vfe);
+zr_detach_codec:
+	videocodec_detach(zr->codec);
+zr_free_codec:
+	kfree(master_codec);
+zr_unreg_i2c:
+	zoran_unregister_i2c(zr);
+zr_free_irq:
+	btwrite(0, ZR36057_SPGPPCR);
+	free_irq(zr->pci_dev->irq, zr);
+zr_unmap:
+	iounmap(zr->zr36057_mem);
+zr_free_mem:
+	kfree(zr);
+
+	return -ENODEV;
 }
 
-static int __init
-init_dc10_cards (void)
+static struct pci_driver zoran_driver = {
+	.name = "zr36067",
+	.id_table = zr36067_pci_tbl,
+	.probe = zoran_probe,
+	.remove = zoran_remove,
+};
+
+static int __init zoran_init(void)
 {
-	int i;
+	int res;
 
-	memset(zoran, 0, sizeof(zoran));
 	printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
 	       MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
 
-	/* Look for cards */
-	if (find_zr36057() < 0) {
-		return -EIO;
-	}
-	if (zoran_num == 0)
-		return -ENODEV;
-	dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
-		zoran_num);
 	/* check the parameters we have been given, adjust if necessary */
 	if (v4l_nbufs < 2)
 		v4l_nbufs = 2;
@@ -1629,37 +1624,22 @@ init_dc10_cards (void)
 			ZORAN_NAME);
 	}
 
-	/* take care of Natoma chipset and a revision 1 zr36057 */
-	for (i = 0; i < zoran_num; i++) {
-		struct zoran *zr = zoran[i];
-
-		if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
-			zr->jpg_buffers.need_contiguous = 1;
-			dprintk(1,
-				KERN_INFO
-				"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
-				ZR_DEVNAME(zr));
-		}
-
-		if (zr36057_init(zr) < 0) {
-			for (i = 0; i < zoran_num; i++)
-				zoran_release(zoran[i]);
-			return -EIO;
-		}
-		zoran_proc_init(zr);
+	res = pci_register_driver(&zoran_driver);
+	if (res) {
+		dprintk(1,
+			KERN_ERR
+			"%s: Unable to register ZR36057 driver\n",
+			ZORAN_NAME);
+		return res;
 	}
 
 	return 0;
 }
 
-static void __exit
-unload_dc10_cards (void)
+static void __exit zoran_exit(void)
 {
-	int i;
-
-	for (i = 0; i < zoran_num; i++)
-		zoran_release(zoran[i]);
+	pci_unregister_driver(&zoran_driver);
 }
 
-module_init(init_dc10_cards);
-module_exit(unload_dc10_cards);
+module_init(zoran_init);
+module_exit(zoran_exit);
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index e4dc9d29b404f6691447b27426d46482cd50ca1f..4507bdc5e3385d27be3ef23652390c66c28b8056 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -40,8 +40,6 @@ extern int zr36067_debug;
 
 /* Anybody who uses more than four? */
 #define BUZ_MAX 4
-extern int zoran_num;
-extern struct zoran *zoran[BUZ_MAX];
 
 extern struct video_device zoran_template;
 
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index b58b9dda715ccedb80cb4c67a42d8c0b9816a903..120ef235e63d07a3d8a3a9c16ae03006bcbdc4cf 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -1196,83 +1196,54 @@ zoran_close_end_session (struct file *file)
  *   Open a zoran card. Right now the flags stuff is just playing
  */
 
-static int
-zoran_open(struct file  *file)
+static int zoran_open(struct file *file)
 {
-	unsigned int minor = video_devdata(file)->minor;
-	struct zoran *zr = NULL;
+	struct zoran *zr = video_drvdata(file);
 	struct zoran_fh *fh;
-	int i, res, first_open = 0, have_module_locks = 0;
+	int res, first_open = 0;
 
-	lock_kernel();
-	/* find the device */
-	for (i = 0; i < zoran_num; i++) {
-		if (zoran[i]->video_dev->minor == minor) {
-			zr = zoran[i];
-			break;
-		}
-	}
+	dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
 
-	if (!zr) {
-		dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
-		res = -ENODEV;
-		goto open_unlock_and_return;
-	}
+	lock_kernel();
 
 	/* see fs/device.c - the kernel already locks during open(),
 	 * so locking ourselves only causes deadlocks */
 	/*mutex_lock(&zr->resource_lock);*/
 
+	if (zr->user >= 2048) {
+		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
+			ZR_DEVNAME(zr), zr->user);
+		res = -EBUSY;
+		goto fail_unlock;
+	}
+
 	if (!zr->decoder) {
 		dprintk(1,
 			KERN_ERR "%s: no TV decoder loaded for device!\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		goto open_unlock_and_return;
+		goto fail_unlock;
 	}
 
-	/* try to grab a module lock */
-	if (!try_module_get(THIS_MODULE)) {
-		dprintk(1,
-			KERN_ERR
-			"%s: failed to acquire my own lock! PANIC!\n",
-			ZR_DEVNAME(zr));
-		res = -ENODEV;
-		goto open_unlock_and_return;
-	}
 	if (!try_module_get(zr->decoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: failed to grab ownership of i2c decoder\n",
+			"%s: failed to grab ownership of video decoder\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		module_put(THIS_MODULE);
-		goto open_unlock_and_return;
+		goto fail_unlock;
 	}
 	if (zr->encoder &&
 	    !try_module_get(zr->encoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
-			"%s: failed to grab ownership of i2c encoder\n",
+			"%s: failed to grab ownership of video encoder\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		module_put(zr->decoder->driver->driver.owner);
-		module_put(THIS_MODULE);
-		goto open_unlock_and_return;
+		goto fail_decoder;
 	}
 
-	have_module_locks = 1;
-
-	if (zr->user >= 2048) {
-		dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
-			ZR_DEVNAME(zr), zr->user);
-		res = -EBUSY;
-		goto open_unlock_and_return;
-	}
-
-	dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
-
 	/* now, create the open()-specific file_ops struct */
 	fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
 	if (!fh) {
@@ -1281,7 +1252,7 @@ zoran_open(struct file  *file)
 			"%s: zoran_open() - allocation of zoran_fh failed\n",
 			ZR_DEVNAME(zr));
 		res = -ENOMEM;
-		goto open_unlock_and_return;
+		goto fail_encoder;
 	}
 	/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
 	 * on norm-change! */
@@ -1292,9 +1263,8 @@ zoran_open(struct file  *file)
 			KERN_ERR
 			"%s: zoran_open() - allocation of overlay_mask failed\n",
 			ZR_DEVNAME(zr));
-		kfree(fh);
 		res = -ENOMEM;
-		goto open_unlock_and_return;
+		goto fail_fh;
 	}
 
 	if (zr->user++ == 0)
@@ -1319,22 +1289,19 @@ zoran_open(struct file  *file)
 
 	return 0;
 
-open_unlock_and_return:
-	/* if we grabbed locks, release them accordingly */
-	if (have_module_locks) {
-		module_put(zr->decoder->driver->driver.owner);
-		if (zr->encoder) {
-			module_put(zr->encoder->driver->driver.owner);
-		}
-		module_put(THIS_MODULE);
-	}
-
-	/* if there's no device found, we didn't obtain the lock either */
-	if (zr) {
-		/*mutex_unlock(&zr->resource_lock);*/
-	}
+fail_fh:
+	kfree(fh);
+fail_encoder:
+	if (zr->encoder)
+		module_put(zr->encoder->driver->driver.owner);
+fail_decoder:
+	module_put(zr->decoder->driver->driver.owner);
+fail_unlock:
 	unlock_kernel();
 
+	dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
+		ZR_DEVNAME(zr), res, zr->user);
+
 	return res;
 }
 
@@ -1344,8 +1311,8 @@ zoran_close(struct file  *file)
 	struct zoran_fh *fh = file->private_data;
 	struct zoran *zr = fh->zr;
 
-	dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
+	dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
 
 	/* kernel locks (fs/device.c), so don't do that ourselves
 	 * (prevents deadlocks) */
@@ -1391,10 +1358,8 @@ zoran_close(struct file  *file)
 
 	/* release locks on the i2c modules */
 	module_put(zr->decoder->driver->driver.owner);
-	if (zr->encoder) {
-		 module_put(zr->encoder->driver->driver.owner);
-	}
-	module_put(THIS_MODULE);
+	if (zr->encoder)
+		module_put(zr->encoder->driver->driver.owner);
 
 	/*mutex_unlock(&zr->resource_lock);*/
 
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 9bf4ccc93dbf9ff591df4eecc6f4358d527d14fe..55e41afd95ef39c59c8d110e9ebc7eed476e7812 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -94,16 +94,16 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
 /* Call the specified callback for all subdevs matching grp_id (if 0, then
    match them all). Ignore any errors. Note that you cannot add or delete
    a subdev while walking the subdevs list. */
-#define v4l2_device_call_all(dev, grp_id, o, f, args...) 		\
+#define v4l2_device_call_all(dev, grpid, o, f, args...) 		\
 	__v4l2_device_call_subdevs(dev, 				\
-			!(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
+			!(grpid) || sd->grp_id == (grpid), o, f , ##args)
 
 /* Call the specified callback for all subdevs matching grp_id (if 0, then
    match them all). If the callback returns an error other than 0 or
    -ENOIOCTLCMD, then return with that error code. Note that you cannot
    add or delete a subdev while walking the subdevs list. */
-#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) 		\
+#define v4l2_device_call_until_err(dev, grpid, o, f, args...) 		\
 	__v4l2_device_call_subdevs_until_err(dev,			\
-		       !(grp_id) || sd->grp_id == (grp_id), o, f , ##args)
+		       !(grpid) || sd->grp_id == (grpid), o, f , ##args)
 
 #endif