diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 0a3588a9798d..f1c441e085e9 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -278,6 +278,8 @@ Your cooperation is appreciated.
 		associated with block devices.	The binding to the
 		loop devices is handled by mount(8) or losetup(8).
 
+  8 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
+
   8 block	SCSI disk devices (0-15)
 		  0 = /dev/sda		First SCSI disk whole disk
 		 16 = /dev/sdb		Second SCSI disk whole disk
@@ -650,7 +652,7 @@ Your cooperation is appreciated.
 		  2 = /dev/sbpcd2	Panasonic CD-ROM controller 0 unit 2
 		  3 = /dev/sbpcd3	Panasonic CD-ROM controller 0 unit 3
 
- 26 char
+ 26 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
  26 block	Second Matsushita (Panasonic/SoundBlaster) CD-ROM
 		  0 = /dev/sbpcd4	Panasonic CD-ROM controller 1 unit 0
@@ -893,7 +895,7 @@ Your cooperation is appreciated.
 		      ...
  39 block
 
- 40 char
+ 40 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
  40 block
 
@@ -1157,7 +1159,7 @@ Your cooperation is appreciated.
 
 		NAMING CONFLICT -- PROPOSED REVISED NAME /dev/rpda0 etc
 
- 60-63 char	LOCAL/EXPERIMENTAL USE
+ 60-63 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
  60-63 block	LOCAL/EXPERIMENTAL USE
 		Allocated for local/experimental use.  For devices not
@@ -1671,7 +1673,7 @@ Your cooperation is appreciated.
 		disks (see major number 3) except that the limit on
 		partitions is 15.
 
- 93 char
+ 93 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
  93 block	NAND Flash Translation Layer filesystem
 		  0 = /dev/nftla	First NFTL layer
@@ -1679,7 +1681,7 @@ Your cooperation is appreciated.
 		    ...
 		240 = /dev/nftlp	16th NTFL layer
 
- 94 char
+ 94 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
  94 block	IBM S/390 DASD block storage
     		  0 = /dev/dasda First DASD device, major
@@ -1772,7 +1774,7 @@ Your cooperation is appreciated.
 		    ...
 		 15 = /dev/amiraid/ar?p15 15th partition
 
-102 char
+102 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
 102 block	Compressed block device
 		  0 = /dev/cbd/a	First compressed block device, whole device
@@ -2057,7 +2059,7 @@ Your cooperation is appreciated.
 		  1 = /dev/vnet1	2nd virtual network
 		    ...
 
-120-127 char	LOCAL/EXPERIMENTAL USE
+120-127 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
 120-127 block	LOCAL/EXPERIMENTAL USE
 		Allocated for local/experimental use.  For devices not
@@ -2371,7 +2373,7 @@ Your cooperation is appreciated.
 		  1 = /dev/gfax1	GammaLink channel 1
 		    ...
 
-159 char	RESERVED
+159 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
 
 159 block	RESERVED
 
@@ -2959,6 +2961,8 @@ Your cooperation is appreciated.
 		    ...
 		196 = /dev/dvb/adapter3/video0    first video decoder of fourth card
 
+213-215 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
+
 216 char	Bluetooth RFCOMM TTY devices
 		  0 = /dev/rfcomm0		First Bluetooth RFCOMM TTY device
 		  1 = /dev/rfcomm1		Second Bluetooth RFCOMM TTY device
@@ -3001,6 +3005,8 @@ Your cooperation is appreciated.
 		same interface.  For interface documentation see
 		http://www.vmelinux.org/.
 
+222-223 char	RESERVED FOR DYNAMIC ALLOCATION OF MAJOR NUMBERS
+
 224 char	A2232 serial card
 		  0 = /dev/ttyY0		First A2232 port
 		  1 = /dev/ttyY1		Second A2232 port
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 687471dc04a0..001b037f6b98 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -37,6 +37,15 @@ static struct char_device_struct {
 	struct cdev *cdev;		/* will die */
 } *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
 
+/*
+ * Duct tape: free major numbers that can be used below the
+ * primary dynamic character major assignment range 234-254
+ */
+static int free_majors[] = {223, 222, 215, 214, 213, 159, 127,
+			   126, 125, 124, 123, 122, 121, 120,
+			   102, 94, 93, 63, 62, 61, 60, 40,
+			   26, 8 };
+
 /* index in the above */
 static inline int major_to_index(unsigned major)
 {
@@ -84,21 +93,37 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
 
 	mutex_lock(&chrdevs_lock);
 
-	/* temporary */
 	if (major == 0) {
 		for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
+			if (i < CHRDEV_MAJOR_DYN_END)
+				break;
 			if (chrdevs[i] == NULL)
 				break;
 		}
 
-		if (i < CHRDEV_MAJOR_DYN_END)
-			pr_warn("CHRDEV \"%s\" major number %d goes below the dynamic allocation range",
+		/*
+		 * Out of the first dynamic range, OK try this duct-tape
+		 * array of lower majors.
+		 */
+		if (i < CHRDEV_MAJOR_DYN_END) {
+			int j;
+
+			for (j = 0; j < ARRAY_SIZE(free_majors); j++) {
+				if (chrdevs[free_majors[j]] == NULL) {
+					i = free_majors[j];
+					break;
+				}
+			}
+			if (j == ARRAY_SIZE(free_majors)) {
+				pr_warn("CHRDEV \"%s\" out of major numbers",
+					name);
+				ret = -EBUSY;
+				goto out;
+			}
+			pr_info("CHRDEV: \"%s\" using extended dynamic range for major number %d\n",
 				name, i);
-
-		if (i == 0) {
-			ret = -EBUSY;
-			goto out;
 		}
+
 		major = i;
 	}
 
