The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/mv/clk/armada38x_coreclk.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2022 Semihalf.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FressBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/bus.h>
   32 #include <sys/kernel.h>
   33 #include <sys/module.h>
   34 #include <sys/mutex.h>
   35 #include <sys/rman.h>
   36 
   37 #include <machine/bus.h>
   38 #include <machine/fdt.h>
   39 
   40 #include <dev/fdt/simplebus.h>
   41 #include <dev/ofw/ofw_bus.h>
   42 #include <dev/ofw/ofw_bus_subr.h>
   43 #include <dev/extres/clk/clk.h>
   44 
   45 #include <arm/mv/mvwin.h>
   46 #include <arm/mv/mvreg.h>
   47 #include <arm/mv/mvvar.h>
   48 
   49 #include <arm/mv/clk/armada38x_gen.h>
   50 
   51 #include "clkdev_if.h"
   52 
   53 #define ARMADA38X_CORECLK_MAXREG 0
   54 
   55 static struct resource_spec armada38x_coreclk_specs[] = {
   56         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
   57         { -1, 0 }
   58 };
   59 
   60 struct armada38x_coreclk_softc {
   61         struct resource *res;
   62         struct clkdom   *clkdom;
   63         struct mtx      mtx;
   64 };
   65 
   66 static int armada38x_coreclk_attach(device_t dev);
   67 static int armada38x_coreclk_probe(device_t dev);
   68 
   69 static struct armada38x_gen_clknode_def gen_nodes[] =
   70 {
   71         {
   72                 .def = {
   73                         .name = "coreclk_0",
   74                         .id = 0,
   75                         .parent_cnt = 0,
   76                 },
   77         },
   78         {
   79                 .def = {
   80                         .name = "coreclk_2",
   81                         .id = 1,
   82                         .parent_cnt = 0,
   83                 },
   84         }
   85 };
   86 
   87 static int
   88 armada38x_coreclk_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
   89 {
   90         struct armada38x_coreclk_softc *sc;
   91 
   92         sc = device_get_softc(dev);
   93 
   94         if (addr > ARMADA38X_CORECLK_MAXREG)
   95                 return (EINVAL);
   96 
   97         *val = bus_read_4(sc->res, addr);
   98 
   99         return (0);
  100 }
  101 
  102 static int
  103 armada38x_coreclk_write_4(device_t dev, bus_addr_t addr, uint32_t val)
  104 {
  105         struct armada38x_coreclk_softc *sc;
  106 
  107         sc = device_get_softc(dev);
  108 
  109         if (addr > ARMADA38X_CORECLK_MAXREG)
  110                 return (EINVAL);
  111 
  112         bus_write_4(sc->res, addr, val);
  113 
  114         return (0);
  115 }
  116 
  117 static void
  118 armada38x_coreclk_device_lock(device_t dev)
  119 {
  120         struct armada38x_coreclk_softc *sc;
  121 
  122         sc = device_get_softc(dev);
  123         mtx_lock(&sc->mtx);
  124 }
  125 
  126 static void
  127 armada38x_coreclk_device_unlock(device_t dev)
  128 {
  129         struct armada38x_coreclk_softc *sc;
  130 
  131         sc = device_get_softc(dev);
  132         mtx_unlock(&sc->mtx);
  133 }
  134 
  135 static int
  136 armada38x_coreclk_probe(device_t dev)
  137 {
  138 
  139         if (!ofw_bus_status_okay(dev))
  140                 return (ENXIO);
  141 
  142         if (!ofw_bus_is_compatible(dev, "marvell,armada-380-core-clock"))
  143                 return (ENXIO);
  144 
  145         device_set_desc(dev, "ARMADA38X core-clock");
  146 
  147         return (BUS_PROBE_DEFAULT);
  148 }
  149 
  150 static int
  151 armada38x_coreclk_create_coreclk(device_t dev)
  152 {
  153         struct armada38x_coreclk_softc *sc;
  154         int rv, i;
  155 
  156         sc = device_get_softc(dev);
  157 
  158         for (i = 0; i < nitems(gen_nodes); ++i) {
  159                 rv = armada38x_gen_register(sc->clkdom, &gen_nodes[i]);
  160                 if (rv)
  161                         return (rv);
  162         }
  163 
  164         return (rv);
  165 }
  166 
  167 static int
  168 armada38x_coreclk_attach(device_t dev)
  169 {
  170         struct armada38x_coreclk_softc *sc;
  171         int error;
  172 
  173         sc = device_get_softc(dev);
  174 
  175         if (bus_alloc_resources(dev, armada38x_coreclk_specs, &sc->res) != 0) {
  176                 device_printf(dev, "Cannot allocate resources.\n");
  177                 return (ENXIO);
  178         }
  179 
  180         mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
  181 
  182         sc->clkdom = clkdom_create(dev);
  183         if (NULL == sc->clkdom) {
  184                 device_printf(dev, "Cannot create clkdom\n");
  185                 return (ENXIO);
  186         }
  187 
  188         error = armada38x_coreclk_create_coreclk(dev);
  189         if (0 != error) {
  190                 device_printf(dev, "Cannot create coreclk.\n");
  191                 return (error);
  192         }
  193 
  194         if (clkdom_finit(sc->clkdom) != 0)
  195                 panic("Cannot finalize clock domain initialization.\n");
  196 
  197         if (bootverbose)
  198                 clkdom_dump(sc->clkdom);
  199 
  200         return (0);
  201 }
  202 
  203 static device_method_t amada38x_coreclk_methods[] = {
  204         DEVMETHOD(clkdev_write_4,       armada38x_coreclk_write_4),
  205         DEVMETHOD(clkdev_read_4,        armada38x_coreclk_read_4),
  206         DEVMETHOD(clkdev_device_lock,   armada38x_coreclk_device_lock),
  207         DEVMETHOD(clkdev_device_unlock, armada38x_coreclk_device_unlock),
  208 
  209         DEVMETHOD(device_attach,        armada38x_coreclk_attach),
  210         DEVMETHOD(device_probe,         armada38x_coreclk_probe),
  211 
  212         DEVMETHOD_END
  213 };
  214 
  215 static driver_t armada38x_coreclk_driver = {
  216         "armada38x_coreclk",
  217         amada38x_coreclk_methods,
  218         sizeof(struct armada38x_coreclk_softc),
  219 };
  220 
  221 EARLY_DRIVER_MODULE(armada38x_coreclk, simplebus, armada38x_coreclk_driver, 0, 0,
  222     BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);

Cache object: ffeaf75e9ae707806907cb7cec167e74


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.