versatile_scm.c revision 331402
1/* 2 * Copyright (c) 2017 Oleksandr Tymoshenko <gonzo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Ben Gray. 16 * 4. The name of the company nor the name of the author may be used to 17 * endorse or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * SCM - System Control Module 34 */ 35#include <sys/cdefs.h> 36__FBSDID("$FreeBSD: stable/11/sys/arm/versatile/versatile_scm.c 331402 2018-03-23 01:37:31Z gonzo $"); 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/kernel.h> 41#include <sys/module.h> 42#include <sys/bus.h> 43#include <sys/resource.h> 44#include <sys/rman.h> 45#include <sys/lock.h> 46#include <sys/mutex.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50 51#include <dev/ofw/openfirm.h> 52#include <dev/ofw/ofw_bus.h> 53#include <dev/ofw/ofw_bus_subr.h> 54 55#include "versatile_scm.h" 56 57struct versatile_scm_softc { 58 device_t sc_dev; 59 struct resource * sc_mem_res; 60}; 61 62static struct versatile_scm_softc *versatile_scm_sc; 63 64#define versatile_scm_read_4(sc, reg) \ 65 bus_read_4((sc)->sc_mem_res, (reg)) 66#define versatile_scm_write_4(sc, reg, val) \ 67 bus_write_4((sc)->sc_mem_res, (reg), (val)) 68 69static int 70versatile_scm_probe(device_t dev) 71{ 72 if (!ofw_bus_status_okay(dev)) 73 return (ENXIO); 74 75 if (!ofw_bus_is_compatible(dev, "syscon")) 76 return (ENXIO); 77 78 if (versatile_scm_sc) { 79 return (EEXIST); 80 } 81 82 device_set_desc(dev, "Versatile Control Module"); 83 return (BUS_PROBE_DEFAULT); 84} 85 86static int 87versatile_scm_attach(device_t dev) 88{ 89 struct versatile_scm_softc *sc; 90 int rid; 91 92 sc = device_get_softc(dev); 93 sc->sc_dev = dev; 94 95 rid = 0; 96 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 97 98 if (sc->sc_mem_res == NULL) { 99 device_printf(dev, "could not allocate memory resources\n"); 100 return (ENXIO); 101 } 102 103 versatile_scm_sc = sc; 104 105 return (0); 106} 107 108int 109versatile_scm_reg_read_4(uint32_t reg, uint32_t *val) 110{ 111 if (!versatile_scm_sc) 112 return (ENXIO); 113 114 *val = versatile_scm_read_4(versatile_scm_sc, reg); 115 return (0); 116} 117 118int 119versatile_scm_reg_write_4(uint32_t reg, uint32_t val) 120{ 121 if (!versatile_scm_sc) 122 return (ENXIO); 123 124 versatile_scm_write_4(versatile_scm_sc, reg, val); 125 return (0); 126} 127 128static device_method_t versatile_scm_methods[] = { 129 DEVMETHOD(device_probe, versatile_scm_probe), 130 DEVMETHOD(device_attach, versatile_scm_attach), 131 132 DEVMETHOD_END 133}; 134 135static driver_t versatile_scm_driver = { 136 "scm", 137 versatile_scm_methods, 138 sizeof(struct versatile_scm_softc), 139}; 140 141static devclass_t versatile_scm_devclass; 142 143EARLY_DRIVER_MODULE(versatile_scm, simplebus, versatile_scm_driver, versatile_scm_devclass, 0, 0, 144 BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); 145