}
 EXPORT_SYMBOL(nand_scan_tail);
 
+static int nand_attach(struct nand_chip *chip)
+{
+       if (chip->controller->ops && chip->controller->ops->attach_chip)
+               return chip->controller->ops->attach_chip(chip);
+
+       return 0;
+}
+
+static void nand_detach(struct nand_chip *chip)
+{
+       if (chip->controller->ops && chip->controller->ops->detach_chip)
+               chip->controller->ops->detach_chip(chip);
+}
+
 /**
  * nand_scan_with_ids - [NAND Interface] Scan for the NAND device
  * @mtd: MTD device structure
 int nand_scan_with_ids(struct mtd_info *mtd, int maxchips,
                       struct nand_flash_dev *ids)
 {
+       struct nand_chip *chip = mtd_to_nand(mtd);
        int ret;
 
        ret = nand_scan_ident(mtd, maxchips, ids);
-       if (!ret)
-               ret = nand_scan_tail(mtd);
+       if (ret)
+               return ret;
+
+       ret = nand_attach(chip);
+       if (ret)
+               return ret;
+
+       ret = nand_scan_tail(mtd);
+       if (ret)
+               nand_detach(chip);
+
        return ret;
 }
 EXPORT_SYMBOL(nand_scan_with_ids);
 
        /* Free manufacturer priv data. */
        nand_manufacturer_cleanup(chip);
+
+       /* Free controller specific allocations after chip identification */
+       nand_detach(chip);
 }
+
 EXPORT_SYMBOL_GPL(nand_cleanup);
 
 /**
 
        int len;
 };
 
+/**
+ * struct nand_controller_ops - Controller operations
+ *
+ * @attach_chip: this method is called after the NAND detection phase after
+ *              flash ID and MTD fields such as erase size, page size and OOB
+ *              size have been set up. ECC requirements are available if
+ *              provided by the NAND chip or device tree. Typically used to
+ *              choose the appropriate ECC configuration and allocate
+ *              associated resources.
+ *              This hook is optional.
+ * @detach_chip: free all resources allocated/claimed in
+ *              nand_controller_ops->attach_chip().
+ *              This hook is optional.
+ */
+struct nand_controller_ops {
+       int (*attach_chip)(struct nand_chip *chip);
+       void (*detach_chip)(struct nand_chip *chip);
+};
+
 /**
  * struct nand_controller - Structure used to describe a NAND controller
  *
  * @wq:                        wait queue to sleep on if a NAND operation is in
  *                     progress used instead of the per chip wait queue
  *                     when a hw controller is available.
+ * @ops:               NAND controller operations.
  */
 struct nand_controller {
        spinlock_t lock;
        struct nand_chip *active;
        wait_queue_head_t wq;
+       const struct nand_controller_ops *ops;
 };
 
 static inline void nand_controller_init(struct nand_controller *nfc)