/**
  * nand_bch_init - Initialize software BCH ECC engine
- * @mtd: MTD device
+ * @chip: NAND chip object
  *
  * Returns: a pointer to a new NAND BCH control structure, or NULL upon failure
  *
  * @eccsize = 512 (thus, m = 13 is the smallest integer such that 2^m - 1 > 512 * 8)
  * @eccbytes = 7 (7 bytes are required to store m * t = 13 * 4 = 52 bits)
  */
-struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
+int nand_bch_init(struct nand_chip *chip)
 {
-       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct mtd_info *mtd = nand_to_mtd(chip);
        unsigned int m, t, eccsteps, i;
        struct nand_bch_control *nbc = NULL;
        unsigned char *erased_page;
-       unsigned int eccsize = nand->ecc.size;
-       unsigned int eccbytes = nand->ecc.bytes;
-       unsigned int eccstrength = nand->ecc.strength;
+       unsigned int eccsize = chip->ecc.size;
+       unsigned int eccbytes = chip->ecc.bytes;
+       unsigned int eccstrength = chip->ecc.strength;
 
        if (!eccbytes && eccstrength) {
                eccbytes = DIV_ROUND_UP(eccstrength * fls(8 * eccsize), 8);
-               nand->ecc.bytes = eccbytes;
+               chip->ecc.bytes = eccbytes;
        }
 
        if (!eccsize || !eccbytes) {
                pr_warn("ecc parameters not supplied\n");
-               goto fail;
+               return -EINVAL;
        }
 
        m = fls(1+8*eccsize);
 
        nbc = kzalloc(sizeof(*nbc), GFP_KERNEL);
        if (!nbc)
-               goto fail;
+               return -ENOMEM;
+
+       chip->ecc.priv = nbc;
 
        nbc->bch = bch_init(m, t, 0, false);
        if (!nbc->bch)
         * FIXME: we should probably rework the sequencing in nand_scan_tail()
         * to avoid setting those fields twice.
         */
-       nand->ecc.steps = eccsteps;
-       nand->ecc.total = eccsteps * eccbytes;
-       nand->base.ecc.ctx.total = nand->ecc.total;
+       chip->ecc.steps = eccsteps;
+       chip->ecc.total = eccsteps * eccbytes;
+       nand->base.ecc.ctx.total = chip->ecc.total;
        if (mtd_ooblayout_count_eccbytes(mtd) != (eccsteps*eccbytes)) {
                pr_warn("invalid ecc layout\n");
                goto fail;
                nbc->eccmask[i] ^= 0xff;
 
        if (!eccstrength)
-               nand->ecc.strength = (eccbytes * 8) / fls(8 * eccsize);
+               chip->ecc.strength = (eccbytes * 8) / fls(8 * eccsize);
 
-       return nbc;
+       return 0;
 fail:
-       nand_bch_free(nbc);
-       return NULL;
+       nand_bch_free(chip);
+       return -EINVAL;
 }
 EXPORT_SYMBOL(nand_bch_init);
 
  * nand_bch_free - Release NAND BCH ECC resources
  * @nbc: NAND BCH control structure
  */
-void nand_bch_free(struct nand_bch_control *nbc)
+void nand_bch_free(struct nand_chip *chip)
 {
+       struct nand_bch_control *nbc = chip->ecc.priv;
+
        if (nbc) {
                bch_free(nbc->bch);
                kfree(nbc->errloc);
 
 
        /*
         * Don't set layout for BCH4 SW ECC. This will be
-        * generated later in nand_bch_init() later.
+        * generated later during BCH initialization.
         */
        if (nand->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) {
                switch (mtd->oobsize) {
 
        struct mtd_info *mtd = nand_to_mtd(chip);
        struct nand_device *nanddev = mtd_to_nanddev(mtd);
        struct nand_ecc_ctrl *ecc = &chip->ecc;
+       int ret;
 
        if (WARN_ON(ecc->engine_type != NAND_ECC_ENGINE_TYPE_SOFT))
                return -EINVAL;
                        ecc->strength = bytes * 8 / fls(8 * ecc->size);
                }
 
-               /* See nand_bch_init() for details. */
+               /* See the software BCH ECC initialization for details */
                ecc->bytes = 0;
-               ecc->priv = nand_bch_init(mtd);
-               if (!ecc->priv) {
+               ret = nand_bch_init(chip);
+               if (ret) {
                        WARN(1, "BCH ECC initialization failed!\n");
-                       return -EINVAL;
+                       return ret;
                }
+
                return 0;
        default:
                WARN(1, "Unsupported ECC algorithm!\n");
 {
        if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
            chip->ecc.algo == NAND_ECC_ALGO_BCH)
-               nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
+               nand_bch_free(chip);
 
        nanddev_cleanup(&chip->base);
 
 
                /* Reserve one byte for the OMAP marker */
                oobbytes_per_step       = chip->ecc.bytes + 1;
                /* Software BCH library is used for locating errors */
-               chip->ecc.priv          = nand_bch_init(mtd);
-               if (!chip->ecc.priv) {
+               err = nand_bch_init(chip);
+               if (err) {
                        dev_err(dev, "Unable to use BCH library\n");
-                       return -EINVAL;
+                       return err;
                }
                break;
 
                /* Reserve one byte for the OMAP marker */
                oobbytes_per_step       = chip->ecc.bytes + 1;
                /* Software BCH library is used for locating errors */
-               chip->ecc.priv          = nand_bch_init(mtd);
-               if (!chip->ecc.priv) {
+               err = nand_bch_init(chip);
+               if (err) {
                        dev_err(dev, "unable to use BCH library\n");
-                       return -EINVAL;
+                       return err;
                }
                break;
 
        if (!IS_ERR_OR_NULL(info->dma))
                dma_release_channel(info->dma);
        if (nand_chip->ecc.priv) {
-               nand_bch_free(nand_chip->ecc.priv);
+               nand_bch_free(nand_chip);
                nand_chip->ecc.priv = NULL;
        }
        return err;
        int ret;
 
        if (nand_chip->ecc.priv) {
-               nand_bch_free(nand_chip->ecc.priv);
+               nand_bch_free(nand_chip);
                nand_chip->ecc.priv = NULL;
        }
        if (info->dma)
 
 
 struct mtd_info;
 struct nand_chip;
-struct nand_bch_control;
 
 #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH)
 
 /*
  * Initialize BCH encoder/decoder
  */
-struct nand_bch_control *nand_bch_init(struct mtd_info *mtd);
+int nand_bch_init(struct nand_chip *chip);
 /*
  * Release BCH encoder/decoder resources
  */
-void nand_bch_free(struct nand_bch_control *nbc);
+void nand_bch_free(struct nand_chip *chip);
 
 #else /* !CONFIG_MTD_NAND_ECC_SW_BCH */
 
        return -ENOTSUPP;
 }
 
-static inline struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
+static inline int nand_bch_init(struct nand_chip *chip)
 {
-       return NULL;
+       return -ENOTSUPP;
 }
 
-static inline void nand_bch_free(struct nand_bch_control *nbc) {}
+static inline void nand_bch_free(struct nand_chip *chip) {}
 
 #endif /* CONFIG_MTD_NAND_ECC_SW_BCH */