diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 81541452887bd3ce5d868909e3fb753fb3d6b124..d06a8d0534bfcfaab828d5ca16a298181fce282d 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -1142,17 +1142,27 @@ static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
 	return fce;
 }
 
-static int fw_cache_piggyback_on_request(const char *name)
+static int __fw_entry_found(const char *name)
 {
 	struct firmware_cache *fwc = &fw_cache;
 	struct fw_cache_entry *fce;
-	int ret = 0;
 
-	spin_lock(&fwc->name_lock);
 	list_for_each_entry(fce, &fwc->fw_names, list) {
 		if (!strcmp(fce->name, name))
-			goto found;
+			return 1;
 	}
+	return 0;
+}
+
+static int fw_cache_piggyback_on_request(const char *name)
+{
+	struct firmware_cache *fwc = &fw_cache;
+	struct fw_cache_entry *fce;
+	int ret = 0;
+
+	spin_lock(&fwc->name_lock);
+	if (__fw_entry_found(name))
+		goto found;
 
 	fce = alloc_fw_cache_entry(name);
 	if (fce) {
@@ -1229,11 +1239,19 @@ static void dev_cache_fw_image(struct device *dev, void *data)
 		list_del(&fce->list);
 
 		spin_lock(&fwc->name_lock);
-		fwc->cnt++;
-		list_add(&fce->list, &fwc->fw_names);
+		/* only one cache entry for one firmware */
+		if (!__fw_entry_found(fce->name)) {
+			fwc->cnt++;
+			list_add(&fce->list, &fwc->fw_names);
+		} else {
+			free_fw_cache_entry(fce);
+			fce = NULL;
+		}
 		spin_unlock(&fwc->name_lock);
 
-		async_schedule(__async_dev_cache_fw_image, (void *)fce);
+		if (fce)
+			async_schedule(__async_dev_cache_fw_image,
+				       (void *)fce);
 	}
 }
 
@@ -1275,6 +1293,9 @@ static void device_cache_fw_images(void)
 
 	pr_debug("%s\n", __func__);
 
+	/* cancel uncache work */
+	cancel_delayed_work_sync(&fwc->work);
+
 	/*
 	 * use small loading timeout for caching devices' firmware
 	 * because all these firmware images have been loaded