xref: /freebsd/sys/arm64/qoriq/clk/ls1028a_flexspi_clk.c (revision be82b3a0bf72ed3b5f01ac9fcd8dcd3802e3c742)
1ccfa9ac5SWojciech Macek /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3ccfa9ac5SWojciech Macek  *
4ccfa9ac5SWojciech Macek  * Copyright (c) 2021 Alstom Group.
5ccfa9ac5SWojciech Macek  * Copyright (c) 2021 Semihalf.
6ccfa9ac5SWojciech Macek  *
7ccfa9ac5SWojciech Macek  * Redistribution and use in source and binary forms, with or without
8ccfa9ac5SWojciech Macek  * modification, are permitted provided that the following conditions
9ccfa9ac5SWojciech Macek  * are met:
10ccfa9ac5SWojciech Macek  * 1. Redistributions of source code must retain the above copyright
11ccfa9ac5SWojciech Macek  *    notice, this list of conditions and the following disclaimer.
12ccfa9ac5SWojciech Macek  * 2. Redistributions in binary form must reproduce the above copyright
13ccfa9ac5SWojciech Macek  *    notice, this list of conditions and the following disclaimer in the
14ccfa9ac5SWojciech Macek  *    documentation and/or other materials provided with the distribution.
15ccfa9ac5SWojciech Macek  *
16ccfa9ac5SWojciech Macek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17ccfa9ac5SWojciech Macek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18ccfa9ac5SWojciech Macek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ccfa9ac5SWojciech Macek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20ccfa9ac5SWojciech Macek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ccfa9ac5SWojciech Macek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22ccfa9ac5SWojciech Macek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23ccfa9ac5SWojciech Macek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24ccfa9ac5SWojciech Macek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25ccfa9ac5SWojciech Macek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26ccfa9ac5SWojciech Macek  * SUCH DAMAGE.
27ccfa9ac5SWojciech Macek  */
28fdafd315SWarner Losh 
29ccfa9ac5SWojciech Macek #include <sys/param.h>
30ccfa9ac5SWojciech Macek #include <sys/systm.h>
31ccfa9ac5SWojciech Macek #include <sys/bus.h>
32ccfa9ac5SWojciech Macek #include <sys/kernel.h>
33ccfa9ac5SWojciech Macek #include <sys/kobj.h>
34ccfa9ac5SWojciech Macek #include <sys/module.h>
35ccfa9ac5SWojciech Macek #include <sys/malloc.h>
36ccfa9ac5SWojciech Macek #include <sys/rman.h>
37ccfa9ac5SWojciech Macek #include <sys/lock.h>
38ccfa9ac5SWojciech Macek #include <sys/mutex.h>
39ccfa9ac5SWojciech Macek 
40ccfa9ac5SWojciech Macek #include <machine/bus.h>
41ccfa9ac5SWojciech Macek #include <machine/cpu.h>
42ccfa9ac5SWojciech Macek 
43*be82b3a0SEmmanuel Vadot #include <dev/clk/clk_div.h>
44ccfa9ac5SWojciech Macek #include <dev/ofw/openfirm.h>
45ccfa9ac5SWojciech Macek #include <dev/ofw/ofw_bus.h>
46ccfa9ac5SWojciech Macek #include <dev/ofw/ofw_bus_subr.h>
47ccfa9ac5SWojciech Macek 
48ccfa9ac5SWojciech Macek #include "clkdev_if.h"
49ccfa9ac5SWojciech Macek #include "syscon_if.h"
50ccfa9ac5SWojciech Macek 
51ccfa9ac5SWojciech Macek 
52ccfa9ac5SWojciech Macek struct ls1028a_flexspi_clk_softc {
53ccfa9ac5SWojciech Macek 	device_t		dev;
54ccfa9ac5SWojciech Macek 	struct clkdom		*clkdom;
55ccfa9ac5SWojciech Macek 	uint64_t 		reg_offset;
56ccfa9ac5SWojciech Macek 	struct syscon		*syscon;
57ccfa9ac5SWojciech Macek 	struct clk_div_def	clk_def;
58ccfa9ac5SWojciech Macek 	struct mtx		mtx;
59ccfa9ac5SWojciech Macek };
60ccfa9ac5SWojciech Macek 
61ccfa9ac5SWojciech Macek static struct clk_div_table ls1028a_flexspi_div_tbl[] = {
62ccfa9ac5SWojciech Macek 	{ .value = 0, .divider = 1, },
63ccfa9ac5SWojciech Macek 	{ .value = 1, .divider = 2, },
64ccfa9ac5SWojciech Macek 	{ .value = 2, .divider = 3, },
65ccfa9ac5SWojciech Macek 	{ .value = 3, .divider = 4, },
66ccfa9ac5SWojciech Macek 	{ .value = 4, .divider = 5, },
67ccfa9ac5SWojciech Macek 	{ .value = 5, .divider = 6, },
68ccfa9ac5SWojciech Macek 	{ .value = 6, .divider = 7, },
69ccfa9ac5SWojciech Macek 	{ .value = 7, .divider = 8, },
70ccfa9ac5SWojciech Macek 	{ .value = 11, .divider = 12, },
71ccfa9ac5SWojciech Macek 	{ .value = 15, .divider = 16, },
72ccfa9ac5SWojciech Macek 	{ .value = 16, .divider = 20, },
73ccfa9ac5SWojciech Macek 	{ .value = 17, .divider = 24, },
74ccfa9ac5SWojciech Macek 	{ .value = 18, .divider = 28, },
75ccfa9ac5SWojciech Macek 	{ .value = 19, .divider = 32, },
76ccfa9ac5SWojciech Macek 	{ .value = 20, .divider = 80, },
77ccfa9ac5SWojciech Macek 	{}
78ccfa9ac5SWojciech Macek };
79ccfa9ac5SWojciech Macek static struct clk_div_table lx2160a_flexspi_div_tbl[] = {
80ccfa9ac5SWojciech Macek 	{ .value = 1, .divider = 2, },
81ccfa9ac5SWojciech Macek 	{ .value = 3, .divider = 4, },
82ccfa9ac5SWojciech Macek 	{ .value = 5, .divider = 6, },
83ccfa9ac5SWojciech Macek 	{ .value = 7, .divider = 8, },
84ccfa9ac5SWojciech Macek 	{ .value = 11, .divider = 12, },
85ccfa9ac5SWojciech Macek 	{ .value = 15, .divider = 16, },
86ccfa9ac5SWojciech Macek 	{ .value = 16, .divider = 20, },
87ccfa9ac5SWojciech Macek 	{ .value = 17, .divider = 24, },
88ccfa9ac5SWojciech Macek 	{ .value = 18, .divider = 28, },
89ccfa9ac5SWojciech Macek 	{ .value = 19, .divider = 32, },
90ccfa9ac5SWojciech Macek 	{ .value = 20, .divider = 80, },
91ccfa9ac5SWojciech Macek 	{}
92ccfa9ac5SWojciech Macek };
93ccfa9ac5SWojciech Macek 
94ccfa9ac5SWojciech Macek static struct ofw_compat_data compat_data[] = {
95ccfa9ac5SWojciech Macek 	{ "fsl,ls1028a-flexspi-clk",	(uintptr_t)ls1028a_flexspi_div_tbl },
96ccfa9ac5SWojciech Macek 	{ "fsl,lx2160a-flexspi-clk",	(uintptr_t)lx2160a_flexspi_div_tbl },
97ccfa9ac5SWojciech Macek 	{ NULL, 0 }
98ccfa9ac5SWojciech Macek };
99ccfa9ac5SWojciech Macek 
100ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_probe(device_t dev)101ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_probe(device_t dev)
102ccfa9ac5SWojciech Macek {
103ccfa9ac5SWojciech Macek 
104ccfa9ac5SWojciech Macek 	if (!ofw_bus_status_okay(dev))
105ccfa9ac5SWojciech Macek 		return (ENXIO);
106ccfa9ac5SWojciech Macek 
107ccfa9ac5SWojciech Macek 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
108ccfa9ac5SWojciech Macek 		device_set_desc(dev, "NXP FlexSPI clock driver");
109ccfa9ac5SWojciech Macek 		return (BUS_PROBE_DEFAULT);
110ccfa9ac5SWojciech Macek 	}
111ccfa9ac5SWojciech Macek 
112ccfa9ac5SWojciech Macek 	return (ENXIO);
113ccfa9ac5SWojciech Macek }
114ccfa9ac5SWojciech Macek 
115ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_attach(device_t dev)116ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_attach(device_t dev)
117ccfa9ac5SWojciech Macek {
118ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
119ccfa9ac5SWojciech Macek 	const char *oclkname = NULL;
120ccfa9ac5SWojciech Macek 	const char *pclkname[1];
121ccfa9ac5SWojciech Macek 	uint32_t acells;
122ccfa9ac5SWojciech Macek 	uint32_t scells;
123ccfa9ac5SWojciech Macek 	pcell_t cells[4];
124ccfa9ac5SWojciech Macek 	phandle_t node;
125ccfa9ac5SWojciech Macek 	uint64_t reg_size;
126ccfa9ac5SWojciech Macek 	int ret;
127ccfa9ac5SWojciech Macek 	clk_t clk;
128ccfa9ac5SWojciech Macek 
129ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
130ccfa9ac5SWojciech Macek 	sc->dev = dev;
131ccfa9ac5SWojciech Macek 	node = ofw_bus_get_node(dev);
132ccfa9ac5SWojciech Macek 
133ccfa9ac5SWojciech Macek 	/* Parse address-cells and size-cells from the parent node as a fallback */
134ccfa9ac5SWojciech Macek 	if (OF_getencprop(node, "#address-cells", &acells,
135ccfa9ac5SWojciech Macek 	    sizeof(acells)) == -1) {
136ccfa9ac5SWojciech Macek 		if (OF_getencprop(OF_parent(node), "#address-cells", &acells,
137ccfa9ac5SWojciech Macek 		    sizeof(acells)) == -1) {
138ccfa9ac5SWojciech Macek 			acells = 2;
139ccfa9ac5SWojciech Macek 		}
140ccfa9ac5SWojciech Macek 	}
141ccfa9ac5SWojciech Macek 	if (OF_getencprop(node, "#size-cells", &scells,
142ccfa9ac5SWojciech Macek 	    sizeof(scells)) == -1) {
143ccfa9ac5SWojciech Macek 		if (OF_getencprop(OF_parent(node), "#size-cells", &scells,
144ccfa9ac5SWojciech Macek 		    sizeof(scells)) == -1) {
145ccfa9ac5SWojciech Macek 			scells = 1;
146ccfa9ac5SWojciech Macek 		}
147ccfa9ac5SWojciech Macek 	}
148ccfa9ac5SWojciech Macek 	ret = OF_getencprop(node, "reg", cells, (acells + scells) * sizeof(pcell_t));
149ccfa9ac5SWojciech Macek 	if (ret < 0) {
150ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR: failed to read REG property\n");
151ccfa9ac5SWojciech Macek 		return (ENOMEM);
152ccfa9ac5SWojciech Macek 	}
153ccfa9ac5SWojciech Macek 	sc->reg_offset = (uint64_t)cells[0];
154ccfa9ac5SWojciech Macek 	if (acells == 2)
155ccfa9ac5SWojciech Macek 		sc->reg_offset = (sc->reg_offset << 32) | (uint64_t)cells[1];
156ccfa9ac5SWojciech Macek 	reg_size = (uint64_t)cells[acells];
157ccfa9ac5SWojciech Macek 	if (scells == 2)
158ccfa9ac5SWojciech Macek 		reg_size = (reg_size << 32) | (uint64_t)cells[acells + 1];
159ccfa9ac5SWojciech Macek 
160ccfa9ac5SWojciech Macek 	if (reg_size != 4) {
161ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR, expected only single register\n");
162ccfa9ac5SWojciech Macek 		return (EINVAL);
163ccfa9ac5SWojciech Macek 	}
164ccfa9ac5SWojciech Macek 	if (sc->reg_offset >> 32UL) {
165ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR, only 32-bit address offset is supported\n");
166ccfa9ac5SWojciech Macek 		return (EINVAL);
167ccfa9ac5SWojciech Macek 	}
168ccfa9ac5SWojciech Macek 
169ccfa9ac5SWojciech Macek 	/* Get syscon handle */
170ccfa9ac5SWojciech Macek 	ret = SYSCON_GET_HANDLE(dev, &sc->syscon);
171ccfa9ac5SWojciech Macek 	if ((ret != 0) || (sc->syscon == NULL)) {
172ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR: failed to get syscon\n");
173ccfa9ac5SWojciech Macek 		return (EFAULT);
174ccfa9ac5SWojciech Macek 	}
175ccfa9ac5SWojciech Macek 
176ccfa9ac5SWojciech Macek 	/* Initialize access mutex */
177ccfa9ac5SWojciech Macek 	mtx_init(&sc->mtx, "FSL clock mtx", NULL, MTX_DEF);
178ccfa9ac5SWojciech Macek 
179ccfa9ac5SWojciech Macek 	/* Get clock names */
180ccfa9ac5SWojciech Macek 	ret = clk_get_by_ofw_index(dev, node, 0, &clk);
181ccfa9ac5SWojciech Macek 	if (ret) {
182ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR: failed to get parent clock\n");
183ccfa9ac5SWojciech Macek 		return (EINVAL);
184ccfa9ac5SWojciech Macek 	}
185ccfa9ac5SWojciech Macek 	pclkname[0] = clk_get_name(clk);
186ccfa9ac5SWojciech Macek 	ret = clk_parse_ofw_clk_name(dev, node, &oclkname);
187ccfa9ac5SWojciech Macek 	if (ret) {
188ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR: failed to get output clock name\n");
189ccfa9ac5SWojciech Macek 		return (EINVAL);
190ccfa9ac5SWojciech Macek 	}
191ccfa9ac5SWojciech Macek 
192ccfa9ac5SWojciech Macek #ifdef DEBUG
193ccfa9ac5SWojciech Macek 	device_printf(dev, "INFO: pclkname %s, oclkname %s\n", pclkname[0], oclkname);
194ccfa9ac5SWojciech Macek #endif
195ccfa9ac5SWojciech Macek 
196ccfa9ac5SWojciech Macek 	/* Fixup CLK structure */
197ccfa9ac5SWojciech Macek 	sc->clk_def.clkdef.name = oclkname;
198ccfa9ac5SWojciech Macek 	sc->clk_def.clkdef.parent_names = (const char **)pclkname;
199ccfa9ac5SWojciech Macek 	sc->clk_def.offset = (uint32_t)sc->reg_offset;
200ccfa9ac5SWojciech Macek 	sc->clk_def.clkdef.id = 1;
201ccfa9ac5SWojciech Macek 	sc->clk_def.clkdef.parent_cnt = 1;
202ccfa9ac5SWojciech Macek 	sc->clk_def.clkdef.flags =  0;
203ccfa9ac5SWojciech Macek 	sc->clk_def.div_flags = CLK_DIV_WITH_TABLE;
204ccfa9ac5SWojciech Macek 	sc->clk_def.i_shift = 0;
205ccfa9ac5SWojciech Macek 	sc->clk_def.i_width = 5;
206ccfa9ac5SWojciech Macek 	sc->clk_def.div_table = (struct clk_div_table*)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
207ccfa9ac5SWojciech Macek 
208ccfa9ac5SWojciech Macek 	/* Create clock */
209ccfa9ac5SWojciech Macek 	sc->clkdom = clkdom_create(dev);
210ccfa9ac5SWojciech Macek 	if (sc->clkdom == NULL)
211ccfa9ac5SWojciech Macek 		panic("clkdom == NULL");
212ccfa9ac5SWojciech Macek 	ret = clknode_div_register(sc->clkdom, &sc->clk_def);
213ccfa9ac5SWojciech Macek 	if (ret) {
214ccfa9ac5SWojciech Macek 		device_printf(dev, "ERROR: unable to register clock\n");
215ccfa9ac5SWojciech Macek 		return (EINVAL);
216ccfa9ac5SWojciech Macek 	}
217ccfa9ac5SWojciech Macek 	clkdom_finit(sc->clkdom);
218ccfa9ac5SWojciech Macek 
219ccfa9ac5SWojciech Macek 	if (bootverbose)
220ccfa9ac5SWojciech Macek 		clkdom_dump(sc->clkdom);
221ccfa9ac5SWojciech Macek 
222ccfa9ac5SWojciech Macek 	return (0);
223ccfa9ac5SWojciech Macek }
224ccfa9ac5SWojciech Macek 
225ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_detach(device_t dev)226ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_detach(device_t dev)
227ccfa9ac5SWojciech Macek {
228ccfa9ac5SWojciech Macek 
229ccfa9ac5SWojciech Macek 	/* Clock detaching is not supported */
230ccfa9ac5SWojciech Macek 	return (EACCES);
231ccfa9ac5SWojciech Macek }
232ccfa9ac5SWojciech Macek 
233ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_read_4(device_t dev,bus_addr_t addr,uint32_t * val)234ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
235ccfa9ac5SWojciech Macek {
236ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
237ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
238ccfa9ac5SWojciech Macek 
239ccfa9ac5SWojciech Macek 	*val = SYSCON_READ_4(sc->syscon, addr);
240ccfa9ac5SWojciech Macek 
241ccfa9ac5SWojciech Macek 	return (0);
242ccfa9ac5SWojciech Macek }
243ccfa9ac5SWojciech Macek 
244ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_write_4(device_t dev,bus_addr_t addr,uint32_t val)245ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_write_4(device_t dev, bus_addr_t addr, uint32_t val)
246ccfa9ac5SWojciech Macek {
247ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
248ccfa9ac5SWojciech Macek 	int ret;
249ccfa9ac5SWojciech Macek 
250ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
251ccfa9ac5SWojciech Macek 
252ccfa9ac5SWojciech Macek 	ret = SYSCON_WRITE_4(sc->syscon, addr, val);
253ccfa9ac5SWojciech Macek 
254ccfa9ac5SWojciech Macek 	return (ret);
255ccfa9ac5SWojciech Macek }
256ccfa9ac5SWojciech Macek 
257ccfa9ac5SWojciech Macek static int
ls1028a_flexspi_clk_modify_4(device_t dev,bus_addr_t addr,uint32_t clr,uint32_t set)258ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set)
259ccfa9ac5SWojciech Macek {
260ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
261ccfa9ac5SWojciech Macek 	int ret;
262ccfa9ac5SWojciech Macek 
263ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
264ccfa9ac5SWojciech Macek 
265ccfa9ac5SWojciech Macek 	ret = SYSCON_MODIFY_4(sc->syscon, addr, clr, set);
266ccfa9ac5SWojciech Macek 
267ccfa9ac5SWojciech Macek 	return (ret);
268ccfa9ac5SWojciech Macek }
269ccfa9ac5SWojciech Macek 
270ccfa9ac5SWojciech Macek static void
ls1028a_flexspi_clk_device_lock(device_t dev)271ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_device_lock(device_t dev)
272ccfa9ac5SWojciech Macek {
273ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
274ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
275ccfa9ac5SWojciech Macek 
276ccfa9ac5SWojciech Macek 	mtx_lock(&sc->mtx);
277ccfa9ac5SWojciech Macek }
278ccfa9ac5SWojciech Macek 
279ccfa9ac5SWojciech Macek static void
ls1028a_flexspi_clk_device_unlock(device_t dev)280ccfa9ac5SWojciech Macek ls1028a_flexspi_clk_device_unlock(device_t dev)
281ccfa9ac5SWojciech Macek {
282ccfa9ac5SWojciech Macek 	struct ls1028a_flexspi_clk_softc *sc;
283ccfa9ac5SWojciech Macek 
284ccfa9ac5SWojciech Macek 	sc = device_get_softc(dev);
285ccfa9ac5SWojciech Macek 
286ccfa9ac5SWojciech Macek 	mtx_unlock(&sc->mtx);
287ccfa9ac5SWojciech Macek }
288ccfa9ac5SWojciech Macek 
289ccfa9ac5SWojciech Macek static device_method_t ls1028a_flexspi_clk_methods[] = {
290ccfa9ac5SWojciech Macek 	/* Device interface */
291ccfa9ac5SWojciech Macek 	DEVMETHOD(device_probe,		ls1028a_flexspi_clk_probe),
292ccfa9ac5SWojciech Macek 	DEVMETHOD(device_attach,	ls1028a_flexspi_clk_attach),
293ccfa9ac5SWojciech Macek 	DEVMETHOD(device_detach,	ls1028a_flexspi_clk_detach),
294ccfa9ac5SWojciech Macek 
295ccfa9ac5SWojciech Macek 	DEVMETHOD(clkdev_read_4,	ls1028a_flexspi_clk_read_4),
296ccfa9ac5SWojciech Macek 	DEVMETHOD(clkdev_write_4,	ls1028a_flexspi_clk_write_4),
297ccfa9ac5SWojciech Macek 	DEVMETHOD(clkdev_modify_4,	ls1028a_flexspi_clk_modify_4),
298ccfa9ac5SWojciech Macek 	DEVMETHOD(clkdev_device_lock,	ls1028a_flexspi_clk_device_lock),
299ccfa9ac5SWojciech Macek 	DEVMETHOD(clkdev_device_unlock,	ls1028a_flexspi_clk_device_unlock),
300ccfa9ac5SWojciech Macek 
301ccfa9ac5SWojciech Macek 	DEVMETHOD_END
302ccfa9ac5SWojciech Macek };
303ccfa9ac5SWojciech Macek 
304ccfa9ac5SWojciech Macek static DEFINE_CLASS_0(fspi_clk, ls1028a_flexspi_clk_driver, ls1028a_flexspi_clk_methods,
305ccfa9ac5SWojciech Macek     sizeof(struct ls1028a_flexspi_clk_softc));
306ccfa9ac5SWojciech Macek EARLY_DRIVER_MODULE(ls1028a_flexspi_clk, simple_mfd, ls1028a_flexspi_clk_driver,
307d7827042SJohn Baldwin     NULL, NULL, BUS_PASS_TIMER);
308