--- a/include/mtd/ubi-user.h
+++ b/include/mtd/ubi-user.h
@@ -176,6 +176,7 @@
 #define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req)
 /* Detach an MTD device */
 #define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t)
+#define UBI_IOCFDET _IOW(UBI_CTRL_IOC_MAGIC, 99, int32_t)
 
 /* ioctl commands of UBI volume character devices */
 
--- a/ubi-utils/include/libubi.h
+++ b/ubi-utils/include/libubi.h
@@ -48,6 +48,7 @@ typedef void * libubi_t;
  *           number)
  * @mtd_num: MTD device number to attach (used if @mtd_dev_node is %NULL)
  * @mtd_dev_node: path to MTD device node to attach
+ * @force: set if the device should be removed even if it's busy
  * @vid_hdr_offset: VID header offset (%0 means default offset and this is what
  *                  most of the users want)
  * @max_beb_per1024: Maximum expected bad eraseblocks per 1024 eraseblocks
@@ -240,29 +241,33 @@ int ubi_attach(libubi_t desc, const char
  * corresponding UBI device is removed. Returns zero in case of success and %-1
  * in case of failure.
  */
-int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num);
+int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num, int force);
 
 /**
  * ubi_detach - detach an MTD device by its node path.
  * @desc: UBI library descriptor
  * @node: name of the UBI control character device node
  * @mtd_dev_node: path to an MTD device node
+ * @force: set if the device should be removed even if it's busy
  *
  * This function detaches an MTD device @mtd_dev_node from UBI. Returns zero in
  * case of success and %-1 in case of failure.
  */
-int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node);
+int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node,
+	int force);
 
 /**
  * ubi_remove_dev - remove an UBI device.
  * @desc: UBI library descriptor
  * @node: name of the UBI control character device node
  * @ubi_dev: UBI device number to remove
+ * @force: set if the device should be removed even if it's busy
  *
  * This function removes UBI device number @ubi_dev and returns zero in case of
  * success and %-1 in case of failure.
  */
-int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev);
+int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev,
+	int force);
 
 /**
  * ubi_mkvol - create an UBI volume.
--- a/ubi-utils/libubi.c
+++ b/ubi-utils/libubi.c
@@ -808,7 +808,7 @@ int ubi_attach(libubi_t desc, const char
 	return ret;
 }
 
-int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num)
+int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num, int force)
 {
 	int ret, ubi_dev;
 
@@ -818,10 +818,11 @@ int ubi_detach_mtd(libubi_t desc, const
 		return ret;
 	}
 
-	return ubi_remove_dev(desc, node, ubi_dev);
+	return ubi_remove_dev(desc, node, ubi_dev, force);
 }
 
-int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node)
+int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node,
+	int force)
 {
 	int mtd_num;
 
@@ -834,10 +835,10 @@ int ubi_detach(libubi_t desc, const char
 	if (mtd_num == -1)
 		return -1;
 
-	return ubi_detach_mtd(desc, node, mtd_num);
+	return ubi_detach_mtd(desc, node, mtd_num, force);
 }
 
-int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev)
+int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev, int force)
 {
 	int fd, ret;
 
@@ -847,6 +848,10 @@ int ubi_remove_dev(libubi_t desc, const
 	if (fd == -1)
 		return sys_errmsg("cannot open \"%s\"", node);
 	ret = ioctl(fd, UBI_IOCDET, &ubi_dev);
+	if (force)
+		ret = ioctl(fd, UBI_IOCFDET, &ubi_dev);
+	else
+		ret = ioctl(fd, UBI_IOCDET, &ubi_dev);
 	if (ret == -1)
 		goto out_close;
 
--- a/ubi-utils/ubidetach.c
+++ b/ubi-utils/ubidetach.c
@@ -40,6 +40,7 @@ struct args {
 	int mtdn;
 	const char *node;
 	const char *dev;
+	int force;
 };
 
 static struct args args = {
@@ -47,6 +48,7 @@ static struct args args = {
 	.mtdn = -1,
 	.node = NULL,
 	.dev = NULL,
+	.force = 0,
 };
 
 static const char doc[] = PROGRAM_NAME " version " VERSION
@@ -56,13 +58,14 @@ static const char optionsstr[] =
 "-d, --devn=<UBI device number>  UBI device number to delete\n"
 "-p, --dev-path=<path to device> or alternatively, MTD device node path to detach\n"
 "-m, --mtdn=<MTD device number>  or alternatively, MTD device number to detach\n"
+"-f, --force			 Force UBI detach even if it is still busy\n"
 "-h, --help                      print help message\n"
 "-V, --version                   print program version";
 
 static const char usage[] =
 "Usage: " PROGRAM_NAME " [<UBI control device node file name>]\n"
 "\t[-d <UBI device number>] [-m <MTD device number>] [-p <path to device>]\n"
-"\t[--devn=<UBI device number>] [--mtdn=<MTD device number>]\n"
+"\t[--devn=<UBI device number>] [--mtdn=<MTD device number>] [-f]\n"
 "\t[--dev-path=<path to device>]\n"
 "UBI control device defaults to " DEFAULT_CTRL_DEV " if not supplied.\n"
 "Example 1: " PROGRAM_NAME " -p /dev/mtd0 - detach MTD device /dev/mtd0\n"
@@ -83,7 +86,7 @@ static int parse_opt(int argc, char * co
 	while (1) {
 		int key, error = 0;
 
-		key = getopt_long(argc, argv, "p:m:d:hV", long_options, NULL);
+		key = getopt_long(argc, argv, "p:m:d:fhV", long_options, NULL);
 		if (key == -1)
 			break;
 
@@ -104,6 +107,9 @@ static int parse_opt(int argc, char * co
 				return errmsg("bad MTD device number: \"%s\"", optarg);
 
 			break;
+		case 'f':
+			args.force = 1;
+			break;
 
 		case 'h':
 			printf("%s\n\n", doc);
@@ -176,20 +182,22 @@ int main(int argc, char * const argv[])
 	}
 
 	if (args.devn != -1) {
-		err = ubi_remove_dev(libubi, args.node, args.devn);
+		err = ubi_remove_dev(libubi, args.node, args.devn, args.force);
 		if (err) {
 			sys_errmsg("cannot remove ubi%d", args.devn);
 			goto out_libubi;
 		}
 	} else {
 		if (args.dev != NULL) {
-			err = ubi_detach(libubi, args.node, args.dev);
+			err = ubi_detach(libubi, args.node, args.dev,
+					args.force);
 			if (err) {
 				sys_errmsg("cannot detach \"%s\"", args.dev);
 				goto out_libubi;
 			}
 		} else {
-			err = ubi_detach_mtd(libubi, args.node, args.mtdn);
+			err = ubi_detach_mtd(libubi, args.node, args.mtdn,
+					     args.force);
 			if (err) {
 				sys_errmsg("cannot detach mtd%d", args.mtdn);
 				goto out_libubi;
