xref: /freebsd/sys/dev/fdt/simple_mfd.c (revision 18250ec6c089c0c50cbd9fd87d78e03ff89916df)
12091650bSEmmanuel Vadot /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
32091650bSEmmanuel Vadot  *
42091650bSEmmanuel Vadot  * Copyright (c) 2018 Rubicon Communications, LLC (Netgate)
52091650bSEmmanuel Vadot  *
62091650bSEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
72091650bSEmmanuel Vadot  * modification, are permitted provided that the following conditions
82091650bSEmmanuel Vadot  * are met:
92091650bSEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
102091650bSEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
112091650bSEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
122091650bSEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
132091650bSEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
142091650bSEmmanuel Vadot  *
152091650bSEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
162091650bSEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
172091650bSEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
182091650bSEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
192091650bSEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
202091650bSEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
212091650bSEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
222091650bSEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
232091650bSEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
242091650bSEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
252091650bSEmmanuel Vadot  * SUCH DAMAGE.
262091650bSEmmanuel Vadot  *
272091650bSEmmanuel Vadot  */
282091650bSEmmanuel Vadot 
292091650bSEmmanuel Vadot #include <sys/param.h>
302091650bSEmmanuel Vadot #include <sys/systm.h>
312091650bSEmmanuel Vadot #include <sys/bus.h>
322091650bSEmmanuel Vadot #include <sys/kernel.h>
3373155b43SGanbold Tsagaankhuu #include <sys/lock.h>
342091650bSEmmanuel Vadot #include <sys/module.h>
3573155b43SGanbold Tsagaankhuu #include <sys/mutex.h>
3673155b43SGanbold Tsagaankhuu #include <sys/rman.h>
372091650bSEmmanuel Vadot 
382091650bSEmmanuel Vadot #include <machine/bus.h>
392091650bSEmmanuel Vadot 
402091650bSEmmanuel Vadot #include <dev/fdt/simplebus.h>
412091650bSEmmanuel Vadot 
422091650bSEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
432091650bSEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
442091650bSEmmanuel Vadot 
4573155b43SGanbold Tsagaankhuu #include <dev/fdt/simple_mfd.h>
462091650bSEmmanuel Vadot 
472091650bSEmmanuel Vadot device_t simple_mfd_add_device(device_t dev, phandle_t node, u_int order,
482091650bSEmmanuel Vadot     const char *name, int unit, struct simplebus_devinfo *di);
497f8c4c78SMichal Meloun struct simplebus_devinfo *simple_mfd_setup_dinfo(device_t dev, phandle_t node,
507f8c4c78SMichal Meloun     struct simplebus_devinfo *di);
512091650bSEmmanuel Vadot 
5273155b43SGanbold Tsagaankhuu #include "syscon_if.h"
5362e8ccc3SEmmanuel Vadot #include <dev/syscon/syscon.h>
5473155b43SGanbold Tsagaankhuu 
5573155b43SGanbold Tsagaankhuu MALLOC_DECLARE(M_SYSCON);
5673155b43SGanbold Tsagaankhuu 
577f8c4c78SMichal Meloun static uint32_t simple_mfd_syscon_read_4(struct syscon *syscon,
587f8c4c78SMichal Meloun     bus_size_t offset);
5973155b43SGanbold Tsagaankhuu static int simple_mfd_syscon_write_4(struct syscon *syscon, bus_size_t offset,
6073155b43SGanbold Tsagaankhuu     uint32_t val);
6173155b43SGanbold Tsagaankhuu static int simple_mfd_syscon_modify_4(struct syscon *syscon, bus_size_t offset,
6273155b43SGanbold Tsagaankhuu     uint32_t clear_bits, uint32_t set_bits);
6373155b43SGanbold Tsagaankhuu 
6473155b43SGanbold Tsagaankhuu #define	SYSCON_LOCK(_sc)		mtx_lock_spin(&(_sc)->mtx)
6573155b43SGanbold Tsagaankhuu #define	SYSCON_UNLOCK(_sc)		mtx_unlock_spin(&(_sc)->mtx)
6673155b43SGanbold Tsagaankhuu #define	SYSCON_LOCK_INIT(_sc)		mtx_init(&(_sc)->mtx,	\
6773155b43SGanbold Tsagaankhuu     device_get_nameunit((_sc)->dev), "syscon", MTX_SPIN)
6873155b43SGanbold Tsagaankhuu #define	SYSCON_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->mtx);
6973155b43SGanbold Tsagaankhuu #define	SYSCON_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_OWNED);
7073155b43SGanbold Tsagaankhuu #define	SYSCON_ASSERT_UNLOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_NOTOWNED);
7173155b43SGanbold Tsagaankhuu 
7273155b43SGanbold Tsagaankhuu static syscon_method_t simple_mfd_syscon_methods[] = {
73f97f57b5SMichal Meloun 	SYSCONMETHOD(syscon_unlocked_read_4,	simple_mfd_syscon_read_4),
74f97f57b5SMichal Meloun 	SYSCONMETHOD(syscon_unlocked_write_4,	simple_mfd_syscon_write_4),
75f97f57b5SMichal Meloun 	SYSCONMETHOD(syscon_unlocked_modify_4,	simple_mfd_syscon_modify_4),
7673155b43SGanbold Tsagaankhuu 
7773155b43SGanbold Tsagaankhuu 	SYSCONMETHOD_END
7873155b43SGanbold Tsagaankhuu };
7973155b43SGanbold Tsagaankhuu DEFINE_CLASS_1(simple_mfd_syscon, simple_mfd_syscon_class,
8073155b43SGanbold Tsagaankhuu     simple_mfd_syscon_methods, 0, syscon_class);
8173155b43SGanbold Tsagaankhuu 
8273155b43SGanbold Tsagaankhuu static uint32_t
simple_mfd_syscon_read_4(struct syscon * syscon,bus_size_t offset)8373155b43SGanbold Tsagaankhuu simple_mfd_syscon_read_4(struct syscon *syscon, bus_size_t offset)
8473155b43SGanbold Tsagaankhuu {
8573155b43SGanbold Tsagaankhuu 	struct simple_mfd_softc *sc;
8673155b43SGanbold Tsagaankhuu 	uint32_t val;
8773155b43SGanbold Tsagaankhuu 
8873155b43SGanbold Tsagaankhuu 	sc = device_get_softc(syscon->pdev);
8921cc0918SElliott Mitchell 	SYSCON_ASSERT_LOCKED(sc);
9073155b43SGanbold Tsagaankhuu 	val = bus_read_4(sc->mem_res, offset);
9173155b43SGanbold Tsagaankhuu 	return (val);
9273155b43SGanbold Tsagaankhuu }
9373155b43SGanbold Tsagaankhuu 
9473155b43SGanbold Tsagaankhuu static int
simple_mfd_syscon_write_4(struct syscon * syscon,bus_size_t offset,uint32_t val)9573155b43SGanbold Tsagaankhuu simple_mfd_syscon_write_4(struct syscon *syscon, bus_size_t offset,
9673155b43SGanbold Tsagaankhuu     uint32_t val)
9773155b43SGanbold Tsagaankhuu {
9873155b43SGanbold Tsagaankhuu 	struct simple_mfd_softc *sc;
9973155b43SGanbold Tsagaankhuu 
10073155b43SGanbold Tsagaankhuu 	sc = device_get_softc(syscon->pdev);
101f97f57b5SMichal Meloun 	SYSCON_ASSERT_LOCKED(sc);
10273155b43SGanbold Tsagaankhuu 	bus_write_4(sc->mem_res, offset, val);
10373155b43SGanbold Tsagaankhuu 	return (0);
10473155b43SGanbold Tsagaankhuu }
10573155b43SGanbold Tsagaankhuu 
10673155b43SGanbold Tsagaankhuu static int
simple_mfd_syscon_modify_4(struct syscon * syscon,bus_size_t offset,uint32_t clear_bits,uint32_t set_bits)10773155b43SGanbold Tsagaankhuu simple_mfd_syscon_modify_4(struct syscon *syscon, bus_size_t offset,
10873155b43SGanbold Tsagaankhuu     uint32_t clear_bits, uint32_t set_bits)
10973155b43SGanbold Tsagaankhuu {
11073155b43SGanbold Tsagaankhuu 	struct simple_mfd_softc *sc;
11173155b43SGanbold Tsagaankhuu 	uint32_t val;
11273155b43SGanbold Tsagaankhuu 
11373155b43SGanbold Tsagaankhuu 	sc = device_get_softc(syscon->pdev);
114f97f57b5SMichal Meloun 	SYSCON_ASSERT_LOCKED(sc);
11573155b43SGanbold Tsagaankhuu 	val = bus_read_4(sc->mem_res, offset);
11673155b43SGanbold Tsagaankhuu 	val &= ~clear_bits;
11773155b43SGanbold Tsagaankhuu 	val |= set_bits;
11873155b43SGanbold Tsagaankhuu 	bus_write_4(sc->mem_res, offset, val);
11973155b43SGanbold Tsagaankhuu 	return (0);
12073155b43SGanbold Tsagaankhuu }
121f97f57b5SMichal Meloun 
1227f8c4c78SMichal Meloun static int
simple_mfd_syscon_get_handle(device_t dev,struct syscon ** syscon)1237f8c4c78SMichal Meloun simple_mfd_syscon_get_handle(device_t dev, struct syscon **syscon)
1247f8c4c78SMichal Meloun {
1257f8c4c78SMichal Meloun 	struct simple_mfd_softc *sc;
1267f8c4c78SMichal Meloun 
1277f8c4c78SMichal Meloun 	sc = device_get_softc(dev);
1287f8c4c78SMichal Meloun 	*syscon = sc->syscon;
12976eeda85SMichal Meloun 	if (*syscon == NULL)
1307f8c4c78SMichal Meloun 		return (ENODEV);
1317f8c4c78SMichal Meloun 	return (0);
1327f8c4c78SMichal Meloun }
13373155b43SGanbold Tsagaankhuu 
134f97f57b5SMichal Meloun static void
simple_mfd_syscon_lock(device_t dev)135f97f57b5SMichal Meloun simple_mfd_syscon_lock(device_t dev)
136f97f57b5SMichal Meloun {
137f97f57b5SMichal Meloun 	struct simple_mfd_softc *sc;
138f97f57b5SMichal Meloun 
139f97f57b5SMichal Meloun 	sc = device_get_softc(dev);
140f97f57b5SMichal Meloun 	SYSCON_LOCK(sc);
141f97f57b5SMichal Meloun }
142f97f57b5SMichal Meloun 
143f97f57b5SMichal Meloun static void
simple_mfd_syscon_unlock(device_t dev)144f97f57b5SMichal Meloun simple_mfd_syscon_unlock(device_t dev)
145f97f57b5SMichal Meloun {
146f97f57b5SMichal Meloun 	struct simple_mfd_softc *sc;
147f97f57b5SMichal Meloun 
148f97f57b5SMichal Meloun 	sc = device_get_softc(dev);
149f97f57b5SMichal Meloun 	SYSCON_UNLOCK(sc);
150f97f57b5SMichal Meloun }
151f97f57b5SMichal Meloun 
1522091650bSEmmanuel Vadot static int
simple_mfd_probe(device_t dev)1532091650bSEmmanuel Vadot simple_mfd_probe(device_t dev)
1542091650bSEmmanuel Vadot {
1552091650bSEmmanuel Vadot 
1562091650bSEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
1572091650bSEmmanuel Vadot 		return (ENXIO);
1582091650bSEmmanuel Vadot 	if (!ofw_bus_is_compatible(dev, "simple-mfd"))
1592091650bSEmmanuel Vadot 		return (ENXIO);
1602091650bSEmmanuel Vadot 
1612091650bSEmmanuel Vadot 	device_set_desc(dev, "Simple MFD (Multi-Functions Device)");
1622091650bSEmmanuel Vadot 
1632091650bSEmmanuel Vadot 	return (BUS_PROBE_GENERIC);
1642091650bSEmmanuel Vadot }
1652091650bSEmmanuel Vadot 
1662091650bSEmmanuel Vadot static int
simple_mfd_attach(device_t dev)1672091650bSEmmanuel Vadot simple_mfd_attach(device_t dev)
1682091650bSEmmanuel Vadot {
1692091650bSEmmanuel Vadot 	struct simple_mfd_softc *sc;
1702091650bSEmmanuel Vadot 	phandle_t node, child;
17173155b43SGanbold Tsagaankhuu 	int rid;
1722091650bSEmmanuel Vadot 
1732091650bSEmmanuel Vadot 	sc = device_get_softc(dev);
1742091650bSEmmanuel Vadot 	node = ofw_bus_get_node(dev);
1752091650bSEmmanuel Vadot 
17673155b43SGanbold Tsagaankhuu 	sc->dev = dev;
17773155b43SGanbold Tsagaankhuu 	rid = 0;
17873155b43SGanbold Tsagaankhuu 
1792091650bSEmmanuel Vadot 	/* Parse address-cells and size-cells from the parent node as a fallback */
1802091650bSEmmanuel Vadot 	if (OF_getencprop(node, "#address-cells", &sc->sc.acells,
1812091650bSEmmanuel Vadot 	    sizeof(sc->sc.acells)) == -1) {
1822091650bSEmmanuel Vadot 		if (OF_getencprop(OF_parent(node), "#address-cells", &sc->sc.acells,
1832091650bSEmmanuel Vadot 		    sizeof(sc->sc.acells)) == -1) {
1842091650bSEmmanuel Vadot 			sc->sc.acells = 2;
1852091650bSEmmanuel Vadot 		}
1862091650bSEmmanuel Vadot 	}
1872091650bSEmmanuel Vadot 	if (OF_getencprop(node, "#size-cells", &sc->sc.scells,
1882091650bSEmmanuel Vadot 	    sizeof(sc->sc.scells)) == -1) {
1892091650bSEmmanuel Vadot 		if (OF_getencprop(OF_parent(node), "#size-cells", &sc->sc.scells,
1902091650bSEmmanuel Vadot 		    sizeof(sc->sc.scells)) == -1) {
1912091650bSEmmanuel Vadot 			sc->sc.scells = 1;
1922091650bSEmmanuel Vadot 		}
1932091650bSEmmanuel Vadot 	}
1942091650bSEmmanuel Vadot 
1952091650bSEmmanuel Vadot 	/* If the node has a ranges prop, parse it so children mapping will be done correctly */
1962091650bSEmmanuel Vadot 	if (OF_hasprop(node, "ranges")) {
1972091650bSEmmanuel Vadot 		if (simplebus_fill_ranges(node, &sc->sc) < 0) {
1982091650bSEmmanuel Vadot 			device_printf(dev, "could not get ranges\n");
1992091650bSEmmanuel Vadot 			return (ENXIO);
2002091650bSEmmanuel Vadot 		}
2012091650bSEmmanuel Vadot 	}
2022091650bSEmmanuel Vadot 
2032091650bSEmmanuel Vadot 	/* Attach child devices */
2042091650bSEmmanuel Vadot 	for (child = OF_child(node); child > 0; child = OF_peer(child)) {
205accda781SMitchell Horne 		(void)simple_mfd_add_device(dev, child, 0, NULL, -1, NULL);
2062091650bSEmmanuel Vadot 	}
2072091650bSEmmanuel Vadot 
20873155b43SGanbold Tsagaankhuu 	if (ofw_bus_is_compatible(dev, "syscon")) {
20973155b43SGanbold Tsagaankhuu 		sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
210b52d0dc4SEmmanuel Vadot 		    RF_ACTIVE);
21173155b43SGanbold Tsagaankhuu 		if (sc->mem_res == NULL) {
21273155b43SGanbold Tsagaankhuu 			device_printf(dev,
21373155b43SGanbold Tsagaankhuu 			    "Cannot allocate memory resource\n");
21473155b43SGanbold Tsagaankhuu 			return (ENXIO);
21573155b43SGanbold Tsagaankhuu 		}
21673155b43SGanbold Tsagaankhuu 
21773155b43SGanbold Tsagaankhuu 		SYSCON_LOCK_INIT(sc);
21873155b43SGanbold Tsagaankhuu 		sc->syscon = syscon_create_ofw_node(dev,
21973155b43SGanbold Tsagaankhuu 		    &simple_mfd_syscon_class, ofw_bus_get_node(dev));
22073155b43SGanbold Tsagaankhuu 		if (sc->syscon == NULL) {
22173155b43SGanbold Tsagaankhuu 			device_printf(dev,
22273155b43SGanbold Tsagaankhuu 			    "Failed to create/register syscon\n");
22373155b43SGanbold Tsagaankhuu 			return (ENXIO);
22473155b43SGanbold Tsagaankhuu 		}
22573155b43SGanbold Tsagaankhuu 	}
226*18250ec6SJohn Baldwin 	bus_attach_children(dev);
227*18250ec6SJohn Baldwin 	return (0);
2282091650bSEmmanuel Vadot }
2292091650bSEmmanuel Vadot 
23073155b43SGanbold Tsagaankhuu static int
simple_mfd_detach(device_t dev)23173155b43SGanbold Tsagaankhuu simple_mfd_detach(device_t dev)
23273155b43SGanbold Tsagaankhuu {
23373155b43SGanbold Tsagaankhuu 	struct simple_mfd_softc *sc;
23473155b43SGanbold Tsagaankhuu 
23573155b43SGanbold Tsagaankhuu 	sc = device_get_softc(dev);
23673155b43SGanbold Tsagaankhuu 	if (ofw_bus_is_compatible(dev, "syscon")) {
23773155b43SGanbold Tsagaankhuu 		if (sc->syscon != NULL) {
23873155b43SGanbold Tsagaankhuu 			syscon_unregister(sc->syscon);
23973155b43SGanbold Tsagaankhuu 			free(sc->syscon, M_SYSCON);
24073155b43SGanbold Tsagaankhuu 		}
24173155b43SGanbold Tsagaankhuu 
24273155b43SGanbold Tsagaankhuu 		SYSCON_LOCK_DESTROY(sc);
24373155b43SGanbold Tsagaankhuu 
24473155b43SGanbold Tsagaankhuu 		if (sc->mem_res != NULL)
24573155b43SGanbold Tsagaankhuu 			bus_release_resource(dev, SYS_RES_MEMORY, 0,
24673155b43SGanbold Tsagaankhuu 			    sc->mem_res);
24773155b43SGanbold Tsagaankhuu 	}
24873155b43SGanbold Tsagaankhuu 	return (0);
24973155b43SGanbold Tsagaankhuu }
25073155b43SGanbold Tsagaankhuu 
2512091650bSEmmanuel Vadot struct simplebus_devinfo *
simple_mfd_setup_dinfo(device_t dev,phandle_t node,struct simplebus_devinfo * di)2522091650bSEmmanuel Vadot simple_mfd_setup_dinfo(device_t dev, phandle_t node,
2532091650bSEmmanuel Vadot     struct simplebus_devinfo *di)
2542091650bSEmmanuel Vadot {
2552091650bSEmmanuel Vadot 	struct simplebus_softc *sc;
2562091650bSEmmanuel Vadot 	struct simplebus_devinfo *ndi;
2572091650bSEmmanuel Vadot 
2582091650bSEmmanuel Vadot 	sc = device_get_softc(dev);
2592091650bSEmmanuel Vadot 	if (di == NULL)
2602091650bSEmmanuel Vadot 		ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
2612091650bSEmmanuel Vadot 	else
2622091650bSEmmanuel Vadot 		ndi = di;
2632091650bSEmmanuel Vadot 	if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) {
2642091650bSEmmanuel Vadot 		if (di == NULL)
2652091650bSEmmanuel Vadot 			free(ndi, M_DEVBUF);
2662091650bSEmmanuel Vadot 		return (NULL);
2672091650bSEmmanuel Vadot 	}
2682091650bSEmmanuel Vadot 
2692091650bSEmmanuel Vadot 	/* reg resources is from the parent but interrupts is on the node itself */
2702091650bSEmmanuel Vadot 	resource_list_init(&ndi->rl);
2712091650bSEmmanuel Vadot 	ofw_bus_reg_to_rl(dev, OF_parent(node), sc->acells, sc->scells, &ndi->rl);
2722091650bSEmmanuel Vadot 	ofw_bus_intr_to_rl(dev, node, &ndi->rl, NULL);
2732091650bSEmmanuel Vadot 
2742091650bSEmmanuel Vadot 	return (ndi);
2752091650bSEmmanuel Vadot }
2762091650bSEmmanuel Vadot 
2772091650bSEmmanuel Vadot device_t
simple_mfd_add_device(device_t dev,phandle_t node,u_int order,const char * name,int unit,struct simplebus_devinfo * di)2782091650bSEmmanuel Vadot simple_mfd_add_device(device_t dev, phandle_t node, u_int order,
2792091650bSEmmanuel Vadot     const char *name, int unit, struct simplebus_devinfo *di)
2802091650bSEmmanuel Vadot {
2812091650bSEmmanuel Vadot 	struct simplebus_devinfo *ndi;
2822091650bSEmmanuel Vadot 	device_t cdev;
2832091650bSEmmanuel Vadot 
2842091650bSEmmanuel Vadot 	if ((ndi = simple_mfd_setup_dinfo(dev, node, di)) == NULL)
2852091650bSEmmanuel Vadot 		return (NULL);
2862091650bSEmmanuel Vadot 	cdev = device_add_child_ordered(dev, order, name, unit);
2872091650bSEmmanuel Vadot 	if (cdev == NULL) {
2882091650bSEmmanuel Vadot 		device_printf(dev, "<%s>: device_add_child failed\n",
2892091650bSEmmanuel Vadot 		    ndi->obdinfo.obd_name);
2902091650bSEmmanuel Vadot 		resource_list_free(&ndi->rl);
2912091650bSEmmanuel Vadot 		ofw_bus_gen_destroy_devinfo(&ndi->obdinfo);
2922091650bSEmmanuel Vadot 		if (di == NULL)
2932091650bSEmmanuel Vadot 			free(ndi, M_DEVBUF);
2942091650bSEmmanuel Vadot 		return (NULL);
2952091650bSEmmanuel Vadot 	}
2962091650bSEmmanuel Vadot 	device_set_ivars(cdev, ndi);
2972091650bSEmmanuel Vadot 
2982091650bSEmmanuel Vadot 	return(cdev);
2992091650bSEmmanuel Vadot }
3002091650bSEmmanuel Vadot 
3012091650bSEmmanuel Vadot static device_method_t simple_mfd_methods[] = {
3027f8c4c78SMichal Meloun 	/* syscon interface */
3037f8c4c78SMichal Meloun 	DEVMETHOD(syscon_get_handle,	simple_mfd_syscon_get_handle),
304f97f57b5SMichal Meloun 	DEVMETHOD(syscon_device_lock,	simple_mfd_syscon_lock),
305f97f57b5SMichal Meloun 	DEVMETHOD(syscon_device_unlock,	simple_mfd_syscon_unlock),
306f97f57b5SMichal Meloun 
3072091650bSEmmanuel Vadot 	/* Device interface */
3082091650bSEmmanuel Vadot 	DEVMETHOD(device_probe,		simple_mfd_probe),
3092091650bSEmmanuel Vadot 	DEVMETHOD(device_attach,	simple_mfd_attach),
31073155b43SGanbold Tsagaankhuu 	DEVMETHOD(device_detach,	simple_mfd_detach),
3112091650bSEmmanuel Vadot 
3122091650bSEmmanuel Vadot 	DEVMETHOD_END
3132091650bSEmmanuel Vadot };
3142091650bSEmmanuel Vadot 
3152091650bSEmmanuel Vadot DEFINE_CLASS_1(simple_mfd, simple_mfd_driver, simple_mfd_methods,
3162091650bSEmmanuel Vadot   sizeof(struct simple_mfd_softc), simplebus_driver);
3172091650bSEmmanuel Vadot 
3180a73fdb9SJohn Baldwin EARLY_DRIVER_MODULE(simple_mfd, simplebus, simple_mfd_driver, 0, 0,
3190a73fdb9SJohn Baldwin     BUS_PASS_BUS + BUS_PASS_ORDER_LATE);
3202091650bSEmmanuel Vadot MODULE_VERSION(simple_mfd, 1);
321