1*5375fcbdSjmcneill /* $NetBSD: fdt_syscon.c,v 1.3 2018/06/30 20:16:56 jmcneill Exp $ */
25b0333ebSjmcneill
35b0333ebSjmcneill /*-
45b0333ebSjmcneill * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
55b0333ebSjmcneill * All rights reserved.
65b0333ebSjmcneill *
75b0333ebSjmcneill * Redistribution and use in source and binary forms, with or without
85b0333ebSjmcneill * modification, are permitted provided that the following conditions
95b0333ebSjmcneill * are met:
105b0333ebSjmcneill * 1. Redistributions of source code must retain the above copyright
115b0333ebSjmcneill * notice, this list of conditions and the following disclaimer.
125b0333ebSjmcneill * 2. Redistributions in binary form must reproduce the above copyright
135b0333ebSjmcneill * notice, this list of conditions and the following disclaimer in the
145b0333ebSjmcneill * documentation and/or other materials provided with the distribution.
155b0333ebSjmcneill *
165b0333ebSjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175b0333ebSjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185b0333ebSjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195b0333ebSjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205b0333ebSjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
215b0333ebSjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
225b0333ebSjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
235b0333ebSjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
245b0333ebSjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
255b0333ebSjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
265b0333ebSjmcneill * SUCH DAMAGE.
275b0333ebSjmcneill */
285b0333ebSjmcneill
295b0333ebSjmcneill #include <sys/cdefs.h>
30*5375fcbdSjmcneill __KERNEL_RCSID(0, "$NetBSD: fdt_syscon.c,v 1.3 2018/06/30 20:16:56 jmcneill Exp $");
315b0333ebSjmcneill
325b0333ebSjmcneill #include <sys/param.h>
335b0333ebSjmcneill #include <sys/bus.h>
345b0333ebSjmcneill #include <sys/kmem.h>
355b0333ebSjmcneill #include <sys/queue.h>
365b0333ebSjmcneill
375b0333ebSjmcneill #include <libfdt.h>
385b0333ebSjmcneill #include <dev/fdt/fdtvar.h>
395b0333ebSjmcneill
405b0333ebSjmcneill struct syscon;
415b0333ebSjmcneill
425b0333ebSjmcneill struct fdtbus_syscon {
435b0333ebSjmcneill device_t sc_dev;
445b0333ebSjmcneill int sc_phandle;
455b0333ebSjmcneill struct syscon *sc_syscon;
465b0333ebSjmcneill
475b0333ebSjmcneill LIST_ENTRY(fdtbus_syscon) sc_next;
485b0333ebSjmcneill };
495b0333ebSjmcneill
50*5375fcbdSjmcneill static LIST_HEAD(, fdtbus_syscon) fdtbus_syscons =
515b0333ebSjmcneill LIST_HEAD_INITIALIZER(fdtbus_syscons);
525b0333ebSjmcneill
535b0333ebSjmcneill int
fdtbus_register_syscon(device_t dev,int phandle,struct syscon * syscon)545b0333ebSjmcneill fdtbus_register_syscon(device_t dev, int phandle,
555b0333ebSjmcneill struct syscon *syscon)
565b0333ebSjmcneill {
575b0333ebSjmcneill struct fdtbus_syscon *sc;
585b0333ebSjmcneill
595b0333ebSjmcneill sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
605b0333ebSjmcneill sc->sc_dev = dev;
615b0333ebSjmcneill sc->sc_phandle = phandle;
625b0333ebSjmcneill sc->sc_syscon = syscon;
635b0333ebSjmcneill
645b0333ebSjmcneill LIST_INSERT_HEAD(&fdtbus_syscons, sc, sc_next);
655b0333ebSjmcneill
665b0333ebSjmcneill return 0;
675b0333ebSjmcneill }
685b0333ebSjmcneill
695b0333ebSjmcneill static struct fdtbus_syscon *
fdtbus_get_syscon(int phandle)705b0333ebSjmcneill fdtbus_get_syscon(int phandle)
715b0333ebSjmcneill {
725b0333ebSjmcneill struct fdtbus_syscon *sc;
735b0333ebSjmcneill
745b0333ebSjmcneill LIST_FOREACH(sc, &fdtbus_syscons, sc_next) {
755b0333ebSjmcneill if (sc->sc_phandle == phandle)
765b0333ebSjmcneill return sc;
775b0333ebSjmcneill }
785b0333ebSjmcneill
795b0333ebSjmcneill return NULL;
805b0333ebSjmcneill }
815b0333ebSjmcneill
825b0333ebSjmcneill struct syscon *
fdtbus_syscon_acquire(int phandle,const char * prop)835b0333ebSjmcneill fdtbus_syscon_acquire(int phandle, const char *prop)
845b0333ebSjmcneill {
855b0333ebSjmcneill struct fdtbus_syscon *sc;
865b0333ebSjmcneill int sc_phandle;
875b0333ebSjmcneill
885b0333ebSjmcneill sc_phandle = fdtbus_get_phandle(phandle, prop);
895b0333ebSjmcneill if (sc_phandle < 0)
905b0333ebSjmcneill return NULL;
915b0333ebSjmcneill
925b0333ebSjmcneill sc = fdtbus_get_syscon(sc_phandle);
935b0333ebSjmcneill if (sc == NULL)
945b0333ebSjmcneill return NULL;
955b0333ebSjmcneill
965b0333ebSjmcneill return sc->sc_syscon;
975b0333ebSjmcneill }
981ca6c5c5Sjmcneill
991ca6c5c5Sjmcneill struct syscon *
fdtbus_syscon_lookup(int phandle)1001ca6c5c5Sjmcneill fdtbus_syscon_lookup(int phandle)
1011ca6c5c5Sjmcneill {
1021ca6c5c5Sjmcneill struct fdtbus_syscon *sc;
1031ca6c5c5Sjmcneill
1041ca6c5c5Sjmcneill sc = fdtbus_get_syscon(phandle);
1051ca6c5c5Sjmcneill if (sc == NULL)
1061ca6c5c5Sjmcneill return NULL;
1071ca6c5c5Sjmcneill
1081ca6c5c5Sjmcneill return sc->sc_syscon;
1091ca6c5c5Sjmcneill }
110