uboot-d1: add bootloader for upcoming d1 target
[openwrt/staging/mans0n.git] / package / boot / uboot-d1 / patches / 0031-mtd-nand-sunxi-Convert-to-the-driver-model.patch
1 From 3411a9a1be9a8d8fef236a81edbce2a1a8218a32 Mon Sep 17 00:00:00 2001
2 From: Samuel Holland <samuel@sholland.org>
3 Date: Mon, 16 May 2022 00:16:48 -0500
4 Subject: [PATCH 31/90] mtd: nand: sunxi: Convert to the driver model
5
6 Clocks, resets, and pinmuxes are now handled by the driver model, so the
7 only thing the "board" code needs to do is load the driver. This matches
8 the pattern used by other DM raw NAND drivers (there is no NAND uclass).
9
10 The actual board code is now only needed in SPL.
11
12 Signed-off-by: Samuel Holland <samuel@sholland.org>
13 ---
14 board/sunxi/board.c | 5 +-
15 drivers/mtd/nand/raw/sunxi_nand.c | 81 ++++++++++++++++++-------------
16 2 files changed, 49 insertions(+), 37 deletions(-)
17
18 --- a/board/sunxi/board.c
19 +++ b/board/sunxi/board.c
20 @@ -311,7 +311,7 @@ int dram_init(void)
21 return 0;
22 }
23
24 -#if defined(CONFIG_NAND_SUNXI)
25 +#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD)
26 static void nand_pinmux_setup(void)
27 {
28 unsigned int pin;
29 @@ -347,9 +347,6 @@ void board_nand_init(void)
30 {
31 nand_pinmux_setup();
32 nand_clock_setup();
33 -#ifndef CONFIG_SPL_BUILD
34 - sunxi_nand_init();
35 -#endif
36 }
37 #endif /* CONFIG_NAND_SUNXI */
38
39 --- a/drivers/mtd/nand/raw/sunxi_nand.c
40 +++ b/drivers/mtd/nand/raw/sunxi_nand.c
41 @@ -24,11 +24,13 @@
42 * GNU General Public License for more details.
43 */
44
45 +#include <clk.h>
46 #include <common.h>
47 #include <dm.h>
48 #include <malloc.h>
49 #include <memalign.h>
50 #include <nand.h>
51 +#include <reset.h>
52 #include <dm/device_compat.h>
53 #include <dm/devres.h>
54 #include <linux/bitops.h>
55 @@ -260,7 +262,7 @@ static inline struct sunxi_nand_chip *to
56 * NAND Controller structure: stores sunxi NAND controller information
57 *
58 * @controller: base controller structure
59 - * @dev: parent device (used to print error messages)
60 + * @dev: DM device (used to print error messages)
61 * @regs: NAND controller registers
62 * @ahb_clk: NAND Controller AHB clock
63 * @mod_clk: NAND Controller mod clock
64 @@ -273,7 +275,7 @@ static inline struct sunxi_nand_chip *to
65 */
66 struct sunxi_nfc {
67 struct nand_hw_control controller;
68 - struct device *dev;
69 + struct udevice *dev;
70 void __iomem *regs;
71 struct clk *ahb_clk;
72 struct clk *mod_clk;
73 @@ -1772,54 +1774,67 @@ static void sunxi_nand_chips_cleanup(str
74 }
75 #endif /* __UBOOT__ */
76
77 -void sunxi_nand_init(void)
78 +static int sunxi_nand_probe(struct udevice *dev)
79 {
80 - struct sunxi_nfc *nfc;
81 - phys_addr_t regs;
82 - ofnode node;
83 + struct sunxi_nfc *nfc = dev_get_priv(dev);
84 + struct reset_ctl_bulk rst_bulk;
85 + struct clk_bulk clk_bulk;
86 int ret;
87
88 - nfc = kzalloc(sizeof(*nfc), GFP_KERNEL);
89 - if (!nfc)
90 - return;
91 -
92 + nfc->dev = dev;
93 spin_lock_init(&nfc->controller.lock);
94 init_waitqueue_head(&nfc->controller.wq);
95 INIT_LIST_HEAD(&nfc->chips);
96
97 - node = ofnode_by_compatible(ofnode_null(), "allwinner,sun4i-a10-nand");
98 - if (!ofnode_valid(node)) {
99 - pr_err("unable to find nfc node in device tree\n");
100 - goto err;
101 - }
102 -
103 - if (!ofnode_is_enabled(node)) {
104 - pr_err("nfc disabled in device tree\n");
105 - goto err;
106 - }
107 -
108 - regs = ofnode_get_addr(node);
109 - if (regs == FDT_ADDR_T_NONE) {
110 - pr_err("unable to find nfc address in device tree\n");
111 - goto err;
112 - }
113 + nfc->regs = dev_read_addr_ptr(dev);
114 + if (!nfc->regs)
115 + return -EINVAL;
116
117 - nfc->regs = (void *)regs;
118 + ret = reset_get_bulk(dev, &rst_bulk);
119 + if (!ret)
120 + reset_deassert_bulk(&rst_bulk);
121 +
122 + ret = clk_get_bulk(dev, &clk_bulk);
123 + if (!ret)
124 + clk_enable_bulk(&clk_bulk);
125
126 ret = sunxi_nfc_rst(nfc);
127 if (ret)
128 - goto err;
129 + return ret;
130
131 - ret = sunxi_nand_chips_init(node, nfc);
132 + ret = sunxi_nand_chips_init(dev_ofnode(dev), nfc);
133 if (ret) {
134 - dev_err(nfc->dev, "failed to init nand chips\n");
135 - goto err;
136 + dev_err(dev, "failed to init nand chips\n");
137 + return ret;
138 }
139
140 - return;
141 + return 0;
142 +}
143
144 -err:
145 - kfree(nfc);
146 +static const struct udevice_id sunxi_nand_ids[] = {
147 + {
148 + .compatible = "allwinner,sun4i-a10-nand",
149 + },
150 + { }
151 +};
152 +
153 +U_BOOT_DRIVER(sunxi_nand) = {
154 + .name = "sunxi_nand",
155 + .id = UCLASS_MTD,
156 + .of_match = sunxi_nand_ids,
157 + .probe = sunxi_nand_probe,
158 + .priv_auto = sizeof(struct sunxi_nfc),
159 +};
160 +
161 +void board_nand_init(void)
162 +{
163 + struct udevice *dev;
164 + int ret;
165 +
166 + ret = uclass_get_device_by_driver(UCLASS_MTD,
167 + DM_DRIVER_GET(sunxi_nand), &dev);
168 + if (ret && ret != -ENODEV)
169 + pr_err("Failed to initialize sunxi NAND controller: %d\n", ret);
170 }
171
172 MODULE_LICENSE("GPL v2");