Hi On Thu, Jul 14, 2022 at 5:15 AM Samuel Holland <sam...@sholland.org> wrote: > > Clocks, resets, and pinmuxes are now handled by the driver model, so the > only thing the "board" code needs to do is load the driver. This matches > the pattern used by other DM raw NAND drivers (there is no NAND uclass). > > The actual board code is now only needed in SPL. > > Signed-off-by: Samuel Holland <sam...@sholland.org> > --- > > board/sunxi/board.c | 5 +- > 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 21a2407e062f..ea0f33ed31db 100644 > --- a/board/sunxi/board.c > +++ b/board/sunxi/board.c > @@ -315,7 +315,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; > @@ -351,9 +351,6 @@ void board_nand_init(void) > { > nand_pinmux_setup(); > nand_clock_setup(); > -#ifndef CONFIG_SPL_BUILD > - sunxi_nand_init(); > -#endif > } > #endif > > diff --git a/drivers/mtd/nand/raw/sunxi_nand.c > b/drivers/mtd/nand/raw/sunxi_nand.c > index 7185efbebfdd..dda51a39b065 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"); > -- > 2.35.1 >
Reviewed-by: Michael Trimarchi <mich...@amarulasolutions.com> Michael