return ret;
 }
 
+/**
+ * next_peb_for_wl - returns next PEB to be used internally by the
+ * WL sub-system.
+ *
+ * @ubi: UBI device description object
+ */
+static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi)
+{
+       struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+       int pnum;
+
+       if (pool->used == pool->size)
+               return NULL;
+
+       pnum = pool->pebs[pool->used];
+       return ubi->lookuptbl[pnum];
+}
+
+/**
+ * need_wear_leveling - checks whether to trigger a wear leveling work.
+ * UBI fetches free PEB from wl_pool, we check free PEBs from both 'wl_pool'
+ * and 'ubi->free', because free PEB in 'ubi->free' tree maybe moved into
+ * 'wl_pool' by ubi_refill_pools().
+ *
+ * @ubi: UBI device description object
+ */
+static bool need_wear_leveling(struct ubi_device *ubi)
+{
+       int ec;
+       struct ubi_wl_entry *e;
+
+       if (!ubi->used.rb_node)
+               return false;
+
+       e = next_peb_for_wl(ubi);
+       if (!e) {
+               if (!ubi->free.rb_node)
+                       return false;
+               e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+               ec = e->ec;
+       } else {
+               ec = e->ec;
+               if (ubi->free.rb_node) {
+                       e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+                       ec = max(ec, e->ec);
+               }
+       }
+       e = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
+
+       return ec - e->ec >= UBI_WL_THRESHOLD;
+}
+
 /* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system.
  *
  * @ubi: UBI device description object
 
        ubi_assert(!ubi->move_from && !ubi->move_to);
        ubi_assert(!ubi->move_to_put);
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+       if (!next_peb_for_wl(ubi) ||
+#else
        if (!ubi->free.rb_node ||
+#endif
            (!ubi->used.rb_node && !ubi->scrub.rb_node)) {
                /*
                 * No free physical eraseblocks? Well, they must be waiting in
 static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
 {
        int err = 0;
-       struct ubi_wl_entry *e1;
-       struct ubi_wl_entry *e2;
        struct ubi_work *wrk;
 
        spin_lock(&ubi->wl_lock);
         * the WL worker has to be scheduled anyway.
         */
        if (!ubi->scrub.rb_node) {
+#ifdef CONFIG_MTD_UBI_FASTMAP
+               if (!need_wear_leveling(ubi))
+                       goto out_unlock;
+#else
+               struct ubi_wl_entry *e1;
+               struct ubi_wl_entry *e2;
+
                if (!ubi->used.rb_node || !ubi->free.rb_node)
                        /* No physical eraseblocks - no deal */
                        goto out_unlock;
 
                if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD))
                        goto out_unlock;
+#endif
                dbg_wl("schedule wear-leveling");
        } else
                dbg_wl("schedule scrubbing");
 
 static void update_fastmap_work_fn(struct work_struct *wrk);
 static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
+static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi);
+static bool need_wear_leveling(struct ubi_device *ubi);
 static void ubi_fastmap_close(struct ubi_device *ubi);
 static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
 {