int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
 {
+       int ret_code;
        ops->retlen = ops->oobretlen = 0;
        if (!mtd->_read_oob)
                return -EOPNOTSUPP;
-       return mtd->_read_oob(mtd, from, ops);
+       /*
+        * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
+        * similar to mtd->_read(), returning a non-negative integer
+        * representing max bitflips. In other cases, mtd->_read_oob() may
+        * return -EUCLEAN. In all cases, perform similar logic to mtd_read().
+        */
+       ret_code = mtd->_read_oob(mtd, from, ops);
+       if (unlikely(ret_code < 0))
+               return ret_code;
+       if (mtd->ecc_strength == 0)
+               return 0;       /* device lacks ecc */
+       return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
 }
 EXPORT_SYMBOL_GPL(mtd_read_oob);