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/powerpc/powermac/uninorth.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) 2002 Benno Rice.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * $FreeBSD$
   28  */
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/module.h>
   33 #include <sys/bus.h>
   34 #include <sys/conf.h>
   35 #include <sys/kernel.h>
   36 
   37 #include <dev/ofw/openfirm.h>
   38 #include <dev/ofw/ofw_pci.h>
   39 #include <dev/ofw/ofw_bus.h>
   40 #include <dev/ofw/ofw_bus_subr.h>
   41 
   42 #include <dev/pci/pcivar.h>
   43 #include <dev/pci/pcireg.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/intr_machdep.h>
   47 #include <machine/md_var.h>
   48 #include <machine/pio.h>
   49 #include <machine/resource.h>
   50 
   51 #include <sys/rman.h>
   52 
   53 #include <powerpc/powermac/uninorthvar.h>
   54 
   55 #include <vm/vm.h>
   56 #include <vm/pmap.h>
   57 
   58 /*
   59  * Driver for the Uninorth chip itself.
   60  */
   61 
   62 static MALLOC_DEFINE(M_UNIN, "unin", "unin device information");
   63 
   64 /*
   65  * Device interface.
   66  */
   67 
   68 static int  unin_chip_probe(device_t);
   69 static int  unin_chip_attach(device_t);
   70 
   71 /*
   72  * Bus interface.
   73  */
   74 static int  unin_chip_print_child(device_t dev, device_t child);
   75 static void unin_chip_probe_nomatch(device_t, device_t);
   76 static struct resource *unin_chip_alloc_resource(device_t, device_t, int, int *,
   77                                                  rman_res_t, rman_res_t,
   78                                                  rman_res_t, u_int);
   79 static int  unin_chip_activate_resource(device_t, device_t, int, int,
   80                                         struct resource *);
   81 static int  unin_chip_deactivate_resource(device_t, device_t, int, int,
   82                                           struct resource *);
   83 static int  unin_chip_release_resource(device_t, device_t, int, int,
   84                                        struct resource *);
   85 static struct resource_list *unin_chip_get_resource_list (device_t, device_t);
   86 
   87 /*
   88  * OFW Bus interface
   89  */
   90 
   91 static ofw_bus_get_devinfo_t unin_chip_get_devinfo;
   92 
   93 /*
   94  * Local routines
   95  */
   96 
   97 static void             unin_enable_gmac(device_t dev);
   98 static void             unin_enable_mpic(device_t dev);
   99 
  100 /*
  101  * Driver methods.
  102  */
  103 static device_method_t unin_chip_methods[] = {
  104         /* Device interface */
  105         DEVMETHOD(device_probe,         unin_chip_probe),
  106         DEVMETHOD(device_attach,        unin_chip_attach),
  107 
  108         /* Bus interface */
  109         DEVMETHOD(bus_print_child,      unin_chip_print_child),
  110         DEVMETHOD(bus_probe_nomatch,    unin_chip_probe_nomatch),
  111         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  112         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  113 
  114         DEVMETHOD(bus_alloc_resource,   unin_chip_alloc_resource),
  115         DEVMETHOD(bus_release_resource, unin_chip_release_resource),
  116         DEVMETHOD(bus_activate_resource, unin_chip_activate_resource),
  117         DEVMETHOD(bus_deactivate_resource, unin_chip_deactivate_resource),
  118         DEVMETHOD(bus_get_resource_list, unin_chip_get_resource_list),
  119 
  120         DEVMETHOD(bus_child_pnpinfo,    ofw_bus_gen_child_pnpinfo),
  121 
  122         /* ofw_bus interface */
  123         DEVMETHOD(ofw_bus_get_devinfo,  unin_chip_get_devinfo),
  124         DEVMETHOD(ofw_bus_get_compat,   ofw_bus_gen_get_compat),
  125         DEVMETHOD(ofw_bus_get_model,    ofw_bus_gen_get_model),
  126         DEVMETHOD(ofw_bus_get_name,     ofw_bus_gen_get_name),
  127         DEVMETHOD(ofw_bus_get_node,     ofw_bus_gen_get_node),
  128         DEVMETHOD(ofw_bus_get_type,     ofw_bus_gen_get_type),
  129         { 0, 0 }
  130 };
  131 
  132 static driver_t unin_chip_driver = {
  133         "unin",
  134         unin_chip_methods,
  135         sizeof(struct unin_chip_softc)
  136 };
  137 
  138 /*
  139  * Assume there is only one unin chip in a PowerMac, so that pmu.c functions can
  140  * suspend the chip after the whole rest of the device tree is suspended, not
  141  * earlier.
  142  */
  143 static device_t         unin_chip;
  144 
  145 EARLY_DRIVER_MODULE(unin, ofwbus, unin_chip_driver, 0, 0, BUS_PASS_BUS);
  146 
  147 /*
  148  * Add an interrupt to the dev's resource list if present
  149  */
  150 static void
  151 unin_chip_add_intr(phandle_t devnode, struct unin_chip_devinfo *dinfo)
  152 {
  153         phandle_t iparent;
  154         int     *intr;
  155         int     i, nintr;
  156         int     icells;
  157 
  158         if (dinfo->udi_ninterrupts >= 6) {
  159                 printf("unin: device has more than 6 interrupts\n");
  160                 return;
  161         }
  162 
  163         nintr = OF_getprop_alloc_multi(devnode, "interrupts", sizeof(*intr), 
  164                 (void **)&intr);
  165         if (nintr == -1) {
  166                 nintr = OF_getprop_alloc_multi(devnode, "AAPL,interrupts", 
  167                         sizeof(*intr), (void **)&intr);
  168                 if (nintr == -1)
  169                         return;
  170         }
  171 
  172         if (intr[0] == -1)
  173                 return;
  174 
  175         if (OF_getprop(devnode, "interrupt-parent", &iparent, sizeof(iparent))
  176             <= 0)
  177                 panic("Interrupt but no interrupt parent!\n");
  178 
  179         if (OF_searchprop(iparent, "#interrupt-cells", &icells, sizeof(icells))
  180             <= 0)
  181                 icells = 1;
  182 
  183         for (i = 0; i < nintr; i+=icells) {
  184                 u_int irq = MAP_IRQ(iparent, intr[i]);
  185 
  186                 resource_list_add(&dinfo->udi_resources, SYS_RES_IRQ,
  187                     dinfo->udi_ninterrupts, irq, irq, 1);
  188 
  189                 if (icells > 1) {
  190                         powerpc_config_intr(irq,
  191                             (intr[i+1] & 1) ? INTR_TRIGGER_LEVEL :
  192                             INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
  193                 }
  194 
  195                 dinfo->udi_interrupts[dinfo->udi_ninterrupts] = irq;
  196                 dinfo->udi_ninterrupts++;
  197         }
  198 }
  199 
  200 static void
  201 unin_chip_add_reg(phandle_t devnode, struct unin_chip_devinfo *dinfo)
  202 {
  203         struct  unin_chip_reg *reg;
  204         int     i, nreg;
  205 
  206         nreg = OF_getprop_alloc_multi(devnode, "reg", sizeof(*reg), (void **)&reg);
  207         if (nreg == -1)
  208                 return;
  209 
  210         for (i = 0; i < nreg; i++) {
  211                 resource_list_add(&dinfo->udi_resources, SYS_RES_MEMORY, i,
  212                                   reg[i].mr_base,
  213                                   reg[i].mr_base + reg[i].mr_size,
  214                                   reg[i].mr_size);
  215         }
  216 }
  217 
  218 static void
  219 unin_update_reg(device_t dev, uint32_t regoff, uint32_t set, uint32_t clr)
  220 {
  221         volatile u_int *reg;
  222         struct unin_chip_softc *sc;
  223         u_int32_t tmpl;
  224 
  225         sc = device_get_softc(dev);
  226         reg = (void *)(sc->sc_addr + regoff);
  227         tmpl = inl(reg);
  228         tmpl &= ~clr;
  229         tmpl |= set;
  230         outl(reg, tmpl);
  231 }
  232 
  233 static void
  234 unin_enable_gmac(device_t dev)
  235 {
  236         unin_update_reg(dev, UNIN_CLOCKCNTL, UNIN_CLOCKCNTL_GMAC, 0);
  237 }
  238 
  239 static void
  240 unin_enable_mpic(device_t dev)
  241 {
  242         unin_update_reg(dev, UNIN_TOGGLE_REG, UNIN_MPIC_RESET | UNIN_MPIC_OUTPUT_ENABLE, 0);
  243 }
  244 
  245 static int
  246 unin_chip_probe(device_t dev)
  247 {
  248         const char      *name;
  249 
  250         name = ofw_bus_get_name(dev);
  251 
  252         if (name == NULL)
  253                 return (ENXIO);
  254 
  255         if (strcmp(name, "uni-n") != 0 && strcmp(name, "u3") != 0
  256             && strcmp(name, "u4") != 0)
  257                 return (ENXIO);
  258 
  259         device_set_desc(dev, "Apple UniNorth System Controller");
  260         return (0);
  261 }
  262 
  263 static int
  264 unin_chip_attach(device_t dev)
  265 {
  266         struct unin_chip_softc *sc;
  267         struct unin_chip_devinfo *dinfo;
  268         phandle_t  root;
  269         phandle_t  child;
  270         phandle_t  iparent;
  271         device_t   cdev;
  272         cell_t     acells, scells;
  273         char compat[32];
  274         char name[32];
  275         u_int irq, reg[3];
  276         int error, i = 0;
  277 
  278         sc = device_get_softc(dev);
  279         root = ofw_bus_get_node(dev);
  280 
  281         if (OF_getprop(root, "reg", reg, sizeof(reg)) < 8)
  282                 return (ENXIO);
  283 
  284         acells = scells = 1;
  285         OF_getprop(OF_parent(root), "#address-cells", &acells, sizeof(acells));
  286         OF_getprop(OF_parent(root), "#size-cells", &scells, sizeof(scells));
  287 
  288         i = 0;
  289         sc->sc_physaddr = reg[i++];
  290         if (acells == 2) {
  291                 sc->sc_physaddr <<= 32;
  292                 sc->sc_physaddr |= reg[i++];
  293         }
  294         sc->sc_size = reg[i++];
  295         if (scells == 2) {
  296                 sc->sc_size <<= 32;
  297                 sc->sc_size |= reg[i++];
  298         }
  299 
  300         sc->sc_mem_rman.rm_type = RMAN_ARRAY;
  301         sc->sc_mem_rman.rm_descr = "UniNorth Device Memory";
  302 
  303         error = rman_init(&sc->sc_mem_rman);
  304 
  305         if (error) {
  306                 device_printf(dev, "rman_init() failed. error = %d\n", error);
  307                 return (error);
  308         }
  309 
  310         error = rman_manage_region(&sc->sc_mem_rman, sc->sc_physaddr,
  311                                    sc->sc_physaddr + sc->sc_size - 1);  
  312         if (error) {
  313                 device_printf(dev,
  314                               "rman_manage_region() failed. error = %d\n",
  315                               error);
  316                 return (error);
  317         }
  318 
  319         if (unin_chip == NULL)
  320                 unin_chip = dev;
  321 
  322         /*
  323          * Iterate through the sub-devices
  324          */
  325         for (child = OF_child(root); child != 0; child = OF_peer(child)) {
  326                 dinfo = malloc(sizeof(*dinfo), M_UNIN, M_WAITOK | M_ZERO);
  327                 if (ofw_bus_gen_setup_devinfo(&dinfo->udi_obdinfo, child)
  328                     != 0)
  329                 {
  330                         free(dinfo, M_UNIN);
  331                         continue;
  332                 }
  333 
  334                 resource_list_init(&dinfo->udi_resources);
  335                 dinfo->udi_ninterrupts = 0;
  336                 unin_chip_add_intr(child, dinfo);
  337 
  338                 /*
  339                  * Some Apple machines do have a bug in OF, they miss
  340                  * the interrupt entries on the U3 I2C node. That means they
  341                  * do not have an entry with number of interrupts nor the
  342                  * entry of the interrupt parent handle.
  343                  * We define an interrupt and hardwire it to the /u3/mpic
  344                  * handle.
  345                  */
  346 
  347                 if (OF_getprop(child, "name", name, sizeof(name)) <= 0)
  348                         device_printf(dev, "device has no name!\n");
  349                 if (dinfo->udi_ninterrupts == 0 &&
  350                     (strcmp(name, "i2c-bus") == 0 ||
  351                      strcmp(name, "i2c")  == 0)) {
  352                         if (OF_getprop(child, "interrupt-parent", &iparent,
  353                                        sizeof(iparent)) <= 0) {
  354                                 iparent = OF_finddevice("/u3/mpic");
  355                                 device_printf(dev, "Set /u3/mpic as iparent!\n");
  356                         }
  357                         /* Add an interrupt number 0 to the parent. */
  358                         irq = MAP_IRQ(iparent, 0);
  359                         resource_list_add(&dinfo->udi_resources, SYS_RES_IRQ,
  360                                           dinfo->udi_ninterrupts, irq, irq, 1);
  361                         dinfo->udi_interrupts[dinfo->udi_ninterrupts] = irq;
  362                         dinfo->udi_ninterrupts++;
  363                 }
  364 
  365                 unin_chip_add_reg(child, dinfo);
  366 
  367                 cdev = device_add_child(dev, NULL, -1);
  368                 if (cdev == NULL) {
  369                         device_printf(dev, "<%s>: device_add_child failed\n",
  370                                       dinfo->udi_obdinfo.obd_name);
  371                         resource_list_free(&dinfo->udi_resources);
  372                         ofw_bus_gen_destroy_devinfo(&dinfo->udi_obdinfo);
  373                         free(dinfo, M_UNIN);
  374                         continue;
  375                 }
  376 
  377                 device_set_ivars(cdev, dinfo);
  378         }
  379 
  380         /*
  381          * Only map the first page, since that is where the registers
  382          * of interest lie.
  383          */
  384         sc->sc_addr = (vm_offset_t)pmap_mapdev(sc->sc_physaddr, PAGE_SIZE);
  385 
  386         sc->sc_version = *(u_int *)sc->sc_addr;
  387         device_printf(dev, "Version %d\n", sc->sc_version);
  388 
  389         /*
  390          * Enable the GMAC Ethernet cell and the integrated OpenPIC
  391          * if Open Firmware says they are used.
  392          */
  393         for (child = OF_child(root); child; child = OF_peer(child)) {
  394                 memset(compat, 0, sizeof(compat));
  395                 OF_getprop(child, "compatible", compat, sizeof(compat));
  396                 if (strcmp(compat, "gmac") == 0)
  397                         unin_enable_gmac(dev);
  398                 if (strcmp(compat, "chrp,open-pic") == 0)
  399                         unin_enable_mpic(dev);
  400         }
  401 
  402         /*
  403          * GMAC lives under the PCI bus, so just check if enet is gmac.
  404          */
  405         child = OF_finddevice("enet");
  406         memset(compat, 0, sizeof(compat));
  407         OF_getprop(child, "compatible", compat, sizeof(compat));
  408         if (strcmp(compat, "gmac") == 0)
  409                 unin_enable_gmac(dev);
  410 
  411         return (bus_generic_attach(dev));
  412 }
  413 
  414 static int
  415 unin_chip_print_child(device_t dev, device_t child)
  416 {
  417         struct unin_chip_devinfo *dinfo;
  418         struct resource_list *rl;
  419         int retval = 0;
  420 
  421         dinfo = device_get_ivars(child);
  422         rl = &dinfo->udi_resources;
  423 
  424         retval += bus_print_child_header(dev, child);
  425 
  426         retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
  427         retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
  428 
  429         retval += bus_print_child_footer(dev, child);
  430 
  431         return (retval);
  432 }
  433 
  434 static void
  435 unin_chip_probe_nomatch(device_t dev, device_t child)
  436 {
  437         struct unin_chip_devinfo *dinfo;
  438         struct resource_list *rl;
  439         const char *type;
  440 
  441         if (bootverbose) {
  442                 dinfo = device_get_ivars(child);
  443                 rl = &dinfo->udi_resources;
  444 
  445                 if ((type = ofw_bus_get_type(child)) == NULL)
  446                         type = "(unknown)";
  447                 device_printf(dev, "<%s, %s>", type, ofw_bus_get_name(child));
  448                 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
  449                 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
  450                 printf(" (no driver attached)\n");
  451         }
  452 }
  453 
  454 static struct resource *
  455 unin_chip_alloc_resource(device_t bus, device_t child, int type, int *rid,
  456                          rman_res_t start, rman_res_t end, rman_res_t count,
  457                          u_int flags)
  458 {
  459         struct          unin_chip_softc *sc;
  460         int             needactivate;
  461         struct          resource *rv;
  462         struct          rman *rm;
  463         u_long          adjstart, adjend, adjcount;
  464         struct          unin_chip_devinfo *dinfo;
  465         struct          resource_list_entry *rle;
  466 
  467         sc = device_get_softc(bus);
  468         dinfo = device_get_ivars(child);
  469 
  470         needactivate = flags & RF_ACTIVE;
  471         flags &= ~RF_ACTIVE;
  472 
  473         switch (type) {
  474         case SYS_RES_MEMORY:
  475         case SYS_RES_IOPORT:
  476                 rle = resource_list_find(&dinfo->udi_resources, SYS_RES_MEMORY,
  477                                          *rid);
  478                 if (rle == NULL) {
  479                         device_printf(bus, "no rle for %s memory %d\n",
  480                                       device_get_nameunit(child), *rid);
  481                         return (NULL);
  482                 }
  483 
  484                 rle->end = rle->end - 1; /* Hack? */
  485 
  486                 if (start < rle->start)
  487                         adjstart = rle->start;
  488                 else if (start > rle->end)
  489                         adjstart = rle->end;
  490                 else
  491                         adjstart = start;
  492 
  493                 if (end < rle->start)
  494                         adjend = rle->start;
  495                 else if (end > rle->end)
  496                         adjend = rle->end;
  497                 else
  498                         adjend = end;
  499 
  500                 adjcount = adjend - adjstart;
  501 
  502                 rm = &sc->sc_mem_rman;
  503                 break;
  504 
  505         case SYS_RES_IRQ:
  506                 /* Check for passthrough from subattachments. */
  507                 if (device_get_parent(child) != bus)
  508                         return BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
  509                                                   type, rid, start, end, count,
  510                                                   flags);
  511 
  512                 rle = resource_list_find(&dinfo->udi_resources, SYS_RES_IRQ,
  513                     *rid);
  514                 if (rle == NULL) {
  515                         if (dinfo->udi_ninterrupts >= 6) {
  516                                 device_printf(bus,
  517                                               "%s has more than 6 interrupts\n",
  518                                               device_get_nameunit(child));
  519                                 return (NULL);
  520                         }
  521                         resource_list_add(&dinfo->udi_resources, SYS_RES_IRQ,
  522                                           dinfo->udi_ninterrupts, start, start,
  523                                           1);
  524 
  525                         dinfo->udi_interrupts[dinfo->udi_ninterrupts] = start;
  526                         dinfo->udi_ninterrupts++;
  527                 }
  528 
  529                 return (resource_list_alloc(&dinfo->udi_resources, bus, child,
  530                                             type, rid, start, end, count,
  531                                             flags));
  532         default:
  533                 device_printf(bus, "unknown resource request from %s\n",
  534                               device_get_nameunit(child));
  535                 return (NULL);
  536         }
  537 
  538         rv = rman_reserve_resource(rm, adjstart, adjend, adjcount, flags,
  539                                    child);
  540         if (rv == NULL) {
  541                 device_printf(bus,
  542                               "failed to reserve resource %#lx - %#lx (%#lx)"
  543                               " for %s\n", adjstart, adjend, adjcount,
  544                               device_get_nameunit(child));
  545                 return (NULL);
  546         }
  547 
  548         rman_set_rid(rv, *rid);
  549 
  550         if (needactivate) {
  551                 if (bus_activate_resource(child, type, *rid, rv) != 0) {
  552                         device_printf(bus,
  553                                       "failed to activate resource for %s\n",
  554                                       device_get_nameunit(child));
  555                         rman_release_resource(rv);
  556                         return (NULL);
  557                 }
  558         }
  559 
  560         return (rv);
  561 }
  562 
  563 static int
  564 unin_chip_release_resource(device_t bus, device_t child, int type, int rid,
  565                            struct resource *res)
  566 {
  567         if (rman_get_flags(res) & RF_ACTIVE) {
  568                 int error = bus_deactivate_resource(child, type, rid, res);
  569                 if (error)
  570                         return error;
  571         }
  572 
  573         return (rman_release_resource(res));
  574 }
  575 
  576 static int
  577 unin_chip_activate_resource(device_t bus, device_t child, int type, int rid,
  578                             struct resource *res)
  579 {
  580         void    *p;
  581 
  582         if (type == SYS_RES_IRQ)
  583                 return (bus_activate_resource(bus, type, rid, res));
  584 
  585         if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
  586                 vm_offset_t start;
  587 
  588                 start = (vm_offset_t) rman_get_start(res);
  589 
  590                 if (bootverbose)
  591                         printf("unin mapdev: start %zx, len %jd\n", start,
  592                                rman_get_size(res));
  593 
  594                 p = pmap_mapdev(start, (vm_size_t) rman_get_size(res));
  595                 if (p == NULL)
  596                         return (ENOMEM);
  597                 rman_set_virtual(res, p);
  598                 rman_set_bustag(res, &bs_be_tag);
  599                 rman_set_bushandle(res, (u_long)p);
  600         }
  601 
  602         return (rman_activate_resource(res));
  603 }
  604 
  605 static int
  606 unin_chip_deactivate_resource(device_t bus, device_t child, int type, int rid,
  607                               struct resource *res)
  608 {
  609         /*
  610          * If this is a memory resource, unmap it.
  611          */
  612         if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
  613                 u_int32_t psize;
  614                 
  615                 psize = rman_get_size(res);
  616                 pmap_unmapdev(rman_get_virtual(res), psize);
  617         }
  618 
  619         return (rman_deactivate_resource(res));
  620 }
  621 
  622 static struct resource_list *
  623 unin_chip_get_resource_list (device_t dev, device_t child)
  624 {
  625         struct unin_chip_devinfo *dinfo;
  626 
  627         dinfo = device_get_ivars(child);
  628         return (&dinfo->udi_resources);
  629 }
  630 
  631 static const struct ofw_bus_devinfo *
  632 unin_chip_get_devinfo(device_t dev, device_t child)
  633 {
  634         struct unin_chip_devinfo *dinfo;
  635 
  636         dinfo = device_get_ivars(child);
  637         return (&dinfo->udi_obdinfo);
  638 }
  639 
  640 int
  641 unin_chip_wake(device_t dev)
  642 {
  643 
  644         if (dev == NULL)
  645                 dev = unin_chip;
  646         unin_update_reg(dev, UNIN_PWR_MGMT, UNIN_PWR_NORMAL, UNIN_PWR_MASK);
  647         DELAY(10);
  648         unin_update_reg(dev, UNIN_HWINIT_STATE, UNIN_RUNNING, 0);
  649         DELAY(100);
  650 
  651         return (0);
  652 }
  653 
  654 int
  655 unin_chip_sleep(device_t dev, int idle)
  656 {
  657         if (dev == NULL)
  658                 dev = unin_chip;
  659 
  660         unin_update_reg(dev, UNIN_HWINIT_STATE, UNIN_SLEEPING, 0);
  661         DELAY(10);
  662         if (idle)
  663                 unin_update_reg(dev, UNIN_PWR_MGMT, UNIN_PWR_IDLE2, UNIN_PWR_MASK);
  664         else
  665                 unin_update_reg(dev, UNIN_PWR_MGMT, UNIN_PWR_SLEEP, UNIN_PWR_MASK);
  666         DELAY(10);
  667 
  668         return (0);
  669 }

Cache object: 9cc0274901b9a367244a1fc856df0b04


[ 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.