compat-drivers: add media subsystem drivers v4l2, uvcvideo

This adds backport support for the first media subsystem
drivers:

  * v4l2 - Video4Linux
  * uvcvideo - UVC webcam devices

http://linuxtv.org/wiki/index.php/UVC_Webcam_Devices

I've run time tested these modules and build tested
against all kernels against next-20130328.

1   2.6.24              [  OK  ]
2   2.6.25              [  OK  ]
3   2.6.26              [  OK  ]
4   2.6.27              [  OK  ]
5   2.6.28              [  OK  ]
6   2.6.29              [  OK  ]
7   2.6.30              [  OK  ]
8   2.6.31              [  OK  ]
9   2.6.32              [  OK  ]
10  2.6.33              [  OK  ]
11  2.6.34              [  OK  ]
12  2.6.35              [  OK  ]
13  2.6.36              [  OK  ]
14  2.6.37              [  OK  ]
15  2.6.38              [  OK  ]
16  2.6.39              [  OK  ]
17  3.0.65              [  OK  ]
18  3.1.10              [  OK  ]
19  3.2.38              [  OK  ]
20  3.3.8               [  OK  ]
21  3.4.32              [  OK  ]
22  3.5.7               [  OK  ]
23  3.6.11              [  OK  ]
24  3.7.9               [  OK  ]
25  3.8.0               [  OK  ]
26  3.9-rc1             [  OK  ]

real    23m54.735s
user    660m4.939s
sys     80m26.078s

Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
diff --git a/.blacklist.map b/.blacklist.map
new file mode 100644
index 0000000..84847e7
--- /dev/null
+++ b/.blacklist.map
@@ -0,0 +1,9 @@
+# Update this map when a driver gets renamed or
+# symbols from old drivers get moved to a newer
+# driver. If you have the driver on the right
+# hand side it will be blacklisted upon installation
+# only if you actually installed the driver on the
+# left.
+
+# new-driver	old-driver
+videodev	v4l2-compat-ioctl32
diff --git a/Makefile b/Makefile
index e53c889..3642a8e 100644
--- a/Makefile
+++ b/Makefile
@@ -44,6 +44,9 @@
 obj-$(CONFIG_COMPAT_VIDEO_MODULES) += drivers/gpu/drm/
 obj-$(CONFIG_COMPAT_VIDEO_MODULES) += drivers/video/
 
+obj-$(CONFIG_COMPAT_MEDIA_MODULES) += drivers/media/v4l2-core/
+obj-$(CONFIG_COMPAT_MEDIA_MODULES) += drivers/media/usb/uvc/
+
 ifeq ($(BT),)
 obj-$(CONFIG_COMPAT_WIRELESS) += net/wireless/ net/mac80211/
 obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += drivers/net/wireless/
@@ -163,6 +166,8 @@
 	$(MAKE) -C $(KLIB_BUILD) M=$(PWD) $(KMODDIR_ARG) $(KMODPATH_ARG) \
 		modules_install
 	@./scripts/update-initramfs
+	@./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR)
+	@/sbin/depmod -a
 
 install-scripts:
 	@# All the scripts we can use
diff --git a/config.mk b/config.mk
index 442ee67..3881787 100644
--- a/config.mk
+++ b/config.mk
@@ -739,6 +739,10 @@
 # ATI/AMD Radeon
 export CONFIG_COMPAT_DRM_RADEON=m
 export CONFIG_COMPAT_DRM_RADEON_KMS=y
+ifdef CONFIG_MEDIA_CONTROLLER
+export CONFIG_COMPAT_USB_VIDEO_CLASS=m
+endif #CONFIG_MEDIA_CONTROLLER
+export CONFIG_USB_VIDEO_CLASS=y
 endif #CONFIG_COMPAT_KERNEL_3_2
 
 # Enable nouveau on >= 3.3
@@ -748,3 +752,11 @@
 export CONFIG_COMPAT_NOUVEAU_DEBUG=5
 export CONFIG_COMPAT_NOUVEAU_DEBUG_DEFAULT=3
 endif #CONFIG_COMPAT_KERNEL_3_3
+
+ifndef CONFIG_COMPAT_KERNEL_3_2
+export CONFIG_COMPAT_MEDIA_MODULES=y
+export CONFIG_COMPAT_VIDEO_V4L2=m
+export CONFIG_COMPAT_VIDEOBUF2_CORE=m
+export CONFIG_COMPAT_VIDEOBUF2_VMALLOC=m
+export CONFIG_COMPAT_VIDEOBUF2_MEMOPS=m
+endif #CONFIG_COMPAT_KERNEL_3_2
diff --git a/patches/collateral-evolutions/media/0001-media_entity_info.patch b/patches/collateral-evolutions/media/0001-media_entity_info.patch
new file mode 100644
index 0000000..c590f5a
--- /dev/null
+++ b/patches/collateral-evolutions/media/0001-media_entity_info.patch
@@ -0,0 +1,57 @@
+Patch fa5034c6 added a name to a union part of struct media_entity.
+We can use the same values in older kernels, we just can't access
+them via the union name.
+
+mcgrof@frijol ~/linux-next (git::master)$ git describe --contains fa5034c6
+v3.3-rc1~48^2~416
+
+commit fa5034c667c224be48db31a0d043dba305e8e7a8
+Author: Clemens Ladisch <clemens@ladisch.de>
+Date:   Sat Nov 5 18:42:01 2011 -0300
+
+    [media] media: fix truncated entity specification
+    
+    When enumerating an entity, assign the entire entity specification
+    instead of only the first two words. (This requires giving the
+    specification union a name.)
+    
+    So far, no driver actually uses more than two words, but this will
+    be needed for ALSA entities.
+    
+    Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+    [laurent.pinchart@ideasonboard.com: Rename specification to info]
+    Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+    Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+
+--- a/drivers/media/v4l2-core/v4l2-dev.c
++++ b/drivers/media/v4l2-core/v4l2-dev.c
+@@ -924,8 +924,13 @@ int __video_register_device(struct video
+ 	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
+ 		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+ 		vdev->entity.name = vdev->name;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
+ 		vdev->entity.info.v4l.major = VIDEO_MAJOR;
+ 		vdev->entity.info.v4l.minor = vdev->minor;
++#else
++		vdev->entity.v4l.major = VIDEO_MAJOR;
++		vdev->entity.v4l.minor = vdev->minor;
++#endif
+ 		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
+ 			&vdev->entity);
+ 		if (ret < 0)
+--- a/drivers/media/v4l2-core/v4l2-device.c
++++ b/drivers/media/v4l2-core/v4l2-device.c
+@@ -232,8 +232,13 @@ int v4l2_device_register_subdev_nodes(st
+ 			goto clean_up;
+ 		}
+ #if defined(CONFIG_MEDIA_CONTROLLER)
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
+ 		sd->entity.info.v4l.major = VIDEO_MAJOR;
+ 		sd->entity.info.v4l.minor = vdev->minor;
++#else
++		sd->entity.v4l.major = VIDEO_MAJOR;
++		sd->entity.v4l.minor = vdev->minor;
++#endif
+ #endif
+ 		sd->devnode = vdev;
+ 	}
diff --git a/patches/collateral-evolutions/media/0002-rename-configs.patch b/patches/collateral-evolutions/media/0002-rename-configs.patch
new file mode 100644
index 0000000..8a04e51
--- /dev/null
+++ b/patches/collateral-evolutions/media/0002-rename-configs.patch
@@ -0,0 +1,10 @@
+Used to allow us to build USB_VIDEO_CLASS even if your kernel had it disabled.
+
+--- a/drivers/media/usb/uvc/Makefile
++++ b/drivers/media/usb/uvc/Makefile
+@@ -3,4 +3,4 @@ uvcvideo-objs  := uvc_driver.o uvc_queue
+ ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
+ uvcvideo-objs  += uvc_entity.o
+ endif
+-obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
++obj-$(CONFIG_COMPAT_USB_VIDEO_CLASS) += uvcvideo.o
diff --git a/patches/collateral-evolutions/media/9999-Makefile-disable.patch b/patches/collateral-evolutions/media/9999-Makefile-disable.patch
new file mode 100644
index 0000000..f667ba7
--- /dev/null
+++ b/patches/collateral-evolutions/media/9999-Makefile-disable.patch
@@ -0,0 +1,44 @@
+--- a/drivers/media/v4l2-core/Makefile
++++ b/drivers/media/v4l2-core/Makefile
+@@ -2,35 +2,15 @@
+ # Makefile for the V4L2 core
+ #
+ 
+-tuner-objs	:=	tuner-core.o
+-
+ videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
+ 			v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+-ifeq ($(CONFIG_COMPAT_COMPAT),y)
++ifeq ($(CONFIG_COMPAT),y)
+   videodev-objs += v4l2-compat-ioctl32.o
+ endif
+ 
+-obj-$(CONFIG_COMPAT_VIDEO_V4L2) += videodev.o
+-obj-$(CONFIG_COMPAT_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o
+-obj-$(CONFIG_COMPAT_VIDEO_V4L2) += v4l2-common.o
+-
+-obj-$(CONFIG_COMPAT_VIDEO_TUNER) += tuner.o
+-
+-obj-$(CONFIG_COMPAT_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
+-
+-obj-$(CONFIG_COMPAT_VIDEOBUF_GEN) += videobuf-core.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF_DVB) += videobuf-dvb.o
+-
+-obj-$(CONFIG_COMPAT_VIDEOBUF2_CORE) += videobuf2-core.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
+-obj-$(CONFIG_COMPAT_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
+-
+-ccflags-y += -I$(srctree)/drivers/media/dvb-core
+-ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
+-ccflags-y += -I$(srctree)/drivers/media/tuners
++obj-$(CONFIG_COMPAT_VIDEO_V4L2) += videodev.o
++obj-$(CONFIG_COMPAT_VIDEO_V4L2) += v4l2-common.o
+ 
++obj-$(CONFIG_COMPAT_VIDEOBUF2_CORE) += videobuf2-core.o
++obj-$(CONFIG_COMPAT_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
++obj-$(CONFIG_COMPAT_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
diff --git a/scripts/admin-update.sh b/scripts/admin-update.sh
index d4d7d0b..f82d70b 100755
--- a/scripts/admin-update.sh
+++ b/scripts/admin-update.sh
@@ -85,7 +85,7 @@
 ###
 usage() {
 	printf "Usage: $0 [refresh] [ --help | -h | -b | -s | -n | -p | -c [ -u ] [subsystems]
-       where subsystems can be network, drm or both. Network is enabled by default.\n\n"
+       where subsystems can be network, drm, media or all. Network is enabled by default.\n\n"
 
 	printf "${GREEN}%10s${NORMAL} - Update all your patch offsets using quilt\n" "refresh"
 	printf "${GREEN}%10s${NORMAL} - Only copy over compat code, do not copy driver code\n" "-b"
@@ -227,6 +227,7 @@
 # fetched in by default.
 ENABLE_NETWORK=1
 ENABLE_DRM=1
+ENABLE_MEDIA=1
 ENABLE_UNIFIED=0
 SUBSYSTEMS=
 UNIFIED_DRIVERS=
@@ -418,11 +419,62 @@
 	     drivers/gpu/drm/radeon
 	     drivers/gpu/drm/ttm
 	     drivers/gpu/drm/via
-	     drivers/gpu/drm/vmwgfx"
+	     drivers/gpu/drm/vmwgfx
+	     drivers/media/usb/uvc/"
 
 # UDL uses the new dma-buf API, let's disable this for now
 #DRIVERS="$DRIVERS drivers/gpu/drm/udl"
 
+# Required media headers from include/linux/media
+INCLUDE_MEDIA="
+v4l2-chip-ident.h
+v4l2-common.h
+v4l2-ctrls.h
+v4l2-dev.h
+v4l2-device.h
+v4l2-event.h
+v4l2-fh.h
+v4l2-image-sizes.h
+v4l2-int-device.h
+v4l2-ioctl.h
+v4l2-mediabus.h
+v4l2-mem2mem.h
+v4l2-subdev.h
+videobuf2-core.h
+videobuf2-dma-contig.h
+videobuf2-dma-sg.h
+videobuf2-memops.h
+videobuf2-vmalloc.h
+videobuf-core.h
+videobuf-dma-contig.h
+videobuf-dma-sg.h
+videobuf-dvb.h
+videobuf-vmalloc.h
+"
+
+# Required media headers from include/linux
+INCLUDE_LINUX_MEDIA="
+videodev2.h
+video_output.h
+dma-buf.h
+"
+
+# Required media headers from include/uapi/linux
+INCLUDE_UAPI_LINUX_MEDIA="
+v4l2-common.h
+v4l2-controls.h
+v4l2-dv-timings.h
+v4l2-mediabus.h
+v4l2-subdev.h
+videodev2.h
+"
+
+# Media drivers
+DRIVERS_MEDIA="
+		drivers/media/v4l2-core/
+		drivers/media/usb/uvc/
+		"
+
 rm -rf drivers/
 rm -f code-metrics.txt
 
@@ -433,6 +485,7 @@
 	 include/trace \
 	 include/pcmcia \
 	 include/crypto \
+	 include/media/ \
 	 include/uapi \
 	 include/uapi/linux \
 	 drivers/bcma \
@@ -448,6 +501,7 @@
 	 $DRIVERS_ETH \
 	 $DRIVERS_BT \
 	 $DRIVERS_DRM \
+	 $DRIVERS_MEDIA \
 	 drivers/video
 
 
@@ -582,12 +636,17 @@
 			"network")
 				ENABLE_NETWORK=1
 				ENABLE_DRM=0
+				ENABLE_MEDIA=0
 				shift
 				;;
 			"drm")
 				ENABLE_DRM=1
 				shift
 				;;
+			"media")
+				ENABLE_MEDIA=1
+				shift
+				;;
 			"-h" | "--help")
 				usage $0
 				exit
@@ -611,6 +670,11 @@
 	SUBSYSTEMS+=" drm"
 fi
 
+if [[ "$ENABLE_MEDIA" == "1" ]]; then
+	SUBSYSTEMS+=" media"
+fi
+
+
 if [[ "$ENABLE_NETWORK" == "1" ]]; then
 	# WLAN and bluetooth files
 	copyFiles "$INCLUDE_LINUX_WLAN"			"include/linux"
@@ -691,6 +755,15 @@
 	touch drivers/video/Makefile
 fi
 
+if [[ "$ENABLE_MEDIA" == "1" ]]; then
+	copyFiles "$INCLUDE_LINUX_MEDIA" "include/linux/"
+	copyFiles "$INCLUDE_MEDIA" "include/media"
+	copyFiles "$INCLUDE_UAPI_LINUX_MEDIA"	"include/uapi/linux"
+	copyDirectories "$DRIVERS_MEDIA"
+	perl -pi -e 's|CONFIG_|CONFIG_COMPAT_|g' drivers/media/v4l2-core/Makefile
+fi
+
+
 # Staging drivers in their own directory
 for i in $STAGING_DRIVERS; do
 	if [ ! -d $GIT_TREE/$i ]; then
@@ -821,6 +894,9 @@
 	include/drm/
 	drivers/gpu/drm/
 	"
+export MEDIA_STABLE="
+	$DRIVERS_MEDIA
+	"
 
 get_stable_patches() {
 	SUBSYS=$1
@@ -909,6 +985,7 @@
 
 	echo $NETWORK_STABLE > ${STABLE_PREFIX}network
 	echo $DRM_STABLE > ${STABLE_PREFIX}drm
+	echo $MEDIA_STABLE > ${STABLE_PREFIX}media
 
 	if [[ "$ENABLE_NETWORK" == "1" ]]; then
 		get_stable_patches network
@@ -918,7 +995,11 @@
 		get_stable_patches drm
 	fi
 
-	rm -f ${STABLE_PREFIX}network ${STABLE_PREFIX}drm
+	if [[ "$ENABLE_MEDIA" == "1" ]]; then
+		get_stable_patches media
+	fi
+
+	rm -f ${STABLE_PREFIX}network ${STABLE_PREFIX}drm ${STABLE_PREFIX}media
 	cd $LAST_DIR
 
 fi
diff --git a/scripts/blacklist.sh b/scripts/blacklist.sh
new file mode 100755
index 0000000..921585f
--- /dev/null
+++ b/scripts/blacklist.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+BLACKLIST_CONF="/etc/modprobe.d/backports.conf"
+BLACKLIST_MAP=".blacklist.map"
+
+MODULE_DIR=$1
+MODULE_UPDATES=$2
+
+if [[ ! -d $MODULE_DIR ]]; then
+	exit
+fi
+
+if [[ ! -d $MODULE_UPDATES ]]; then
+	exit
+fi
+
+mkdir -p $(dirname $BLACKLIST_CONF)
+rm -f $BLACKLIST_CONF
+
+echo "# To be used when using backported drivers" >> $BLACKLIST_CONF
+
+for i in $(grep -v ^# $BLACKLIST_MAP | cut -f 2); do
+	MODULE="${i}.ko"
+	MODULE_UPDATE="$(grep -v ^# $BLACKLIST_MAP | grep $i | cut -f 1 | head -1).ko"
+
+	COUNT=$(find $MODULE_DIR -type f -name ${MODULE} -or -name ${MODULE}.gz | wc -l)
+	COUNT_REPLACE=$(find $MODULE_UPDATES -type f -name ${MODULE_UPDATE} -or -name ${MODULE_UPDATE}.gz | wc -l)
+
+	if [ $COUNT -ne 0 ]; then
+		if [ $COUNT_REPLACE -ne 0 ]; then
+			echo "Blacklisting $MODULE ..."
+			echo blacklist $i >> $BLACKLIST_CONF
+		fi
+	fi
+done