diff options
-rw-r--r-- | board/sunxi/board.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sunxi_nand.c | 81 |
2 files changed, 49 insertions, 37 deletions
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 827e545032e..f321cd58a6e 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -311,7 +311,7 @@ int dram_init(void) return 0; } -#if defined(CONFIG_NAND_SUNXI) +#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) static void nand_pinmux_setup(void) { unsigned int pin; @@ -347,9 +347,6 @@ void board_nand_init(void) { nand_pinmux_setup(); nand_clock_setup(); -#ifndef CONFIG_SPL_BUILD - sunxi_nand_init(); -#endif } #endif /* CONFIG_NAND_SUNXI */ diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 7185efbebfd..dda51a39b06 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -24,11 +24,13 @@ * GNU General Public License for more details. */ +#include <clk.h> #include <common.h> #include <dm.h> #include <malloc.h> #include <memalign.h> #include <nand.h> +#include <reset.h> #include <dm/device_compat.h> #include <dm/devres.h> #include <linux/bitops.h> @@ -260,7 +262,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) * NAND Controller structure: stores sunxi NAND controller information * * @controller: base controller structure - * @dev: parent device (used to print error messages) + * @dev: DM device (used to print error messages) * @regs: NAND controller registers * @ahb_clk: NAND Controller AHB clock * @mod_clk: NAND Controller mod clock @@ -273,7 +275,7 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) */ struct sunxi_nfc { struct nand_hw_control controller; - struct device *dev; + struct udevice *dev; void __iomem *regs; struct clk *ahb_clk; struct clk *mod_clk; @@ -1772,54 +1774,67 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) } #endif /* __UBOOT__ */ -void sunxi_nand_init(void) +static int sunxi_nand_probe(struct udevice *dev) { - struct sunxi_nfc *nfc; - phys_addr_t regs; - ofnode node; + struct sunxi_nfc *nfc = dev_get_priv(dev); + struct reset_ctl_bulk rst_bulk; + struct clk_bulk clk_bulk; int ret; - nfc = kzalloc(sizeof(*nfc), GFP_KERNEL); - if (!nfc) - return; - + nfc->dev = dev; spin_lock_init(&nfc->controller.lock); init_waitqueue_head(&nfc->controller.wq); INIT_LIST_HEAD(&nfc->chips); - node = ofnode_by_compatible(ofnode_null(), "allwinner,sun4i-a10-nand"); - if (!ofnode_valid(node)) { - pr_err("unable to find nfc node in device tree\n"); - goto err; - } - - if (!ofnode_is_enabled(node)) { - pr_err("nfc disabled in device tree\n"); - goto err; - } + nfc->regs = dev_read_addr_ptr(dev); + if (!nfc->regs) + return -EINVAL; - regs = ofnode_get_addr(node); - if (regs == FDT_ADDR_T_NONE) { - pr_err("unable to find nfc address in device tree\n"); - goto err; - } + ret = reset_get_bulk(dev, &rst_bulk); + if (!ret) + reset_deassert_bulk(&rst_bulk); - nfc->regs = (void *)regs; + ret = clk_get_bulk(dev, &clk_bulk); + if (!ret) + clk_enable_bulk(&clk_bulk); ret = sunxi_nfc_rst(nfc); if (ret) - goto err; + return ret; - ret = sunxi_nand_chips_init(node, nfc); + ret = sunxi_nand_chips_init(dev_ofnode(dev), nfc); if (ret) { - dev_err(nfc->dev, "failed to init nand chips\n"); - goto err; + dev_err(dev, "failed to init nand chips\n"); + return ret; } - return; + return 0; +} -err: - kfree(nfc); +static const struct udevice_id sunxi_nand_ids[] = { + { + .compatible = "allwinner,sun4i-a10-nand", + }, + { } +}; + +U_BOOT_DRIVER(sunxi_nand) = { + .name = "sunxi_nand", + .id = UCLASS_MTD, + .of_match = sunxi_nand_ids, + .probe = sunxi_nand_probe, + .priv_auto = sizeof(struct sunxi_nfc), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_DRIVER_GET(sunxi_nand), &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize sunxi NAND controller: %d\n", ret); } MODULE_LICENSE("GPL v2"); |