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/dev/extres/regulator/regulator.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  * Copyright 2016 Michal Meloun <mmel@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  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include "opt_platform.h"
   31 #include <sys/param.h>
   32 #include <sys/conf.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <sys/queue.h>
   36 #include <sys/kobj.h>
   37 #include <sys/malloc.h>
   38 #include <sys/mutex.h>
   39 #include <sys/limits.h>
   40 #include <sys/lock.h>
   41 #include <sys/sysctl.h>
   42 #include <sys/systm.h>
   43 #include <sys/sx.h>
   44 
   45 #ifdef FDT
   46 #include <dev/fdt/fdt_common.h>
   47 #include <dev/ofw/ofw_bus.h>
   48 #include <dev/ofw/ofw_bus_subr.h>
   49 #endif
   50 #include <dev/extres/regulator/regulator.h>
   51 
   52 #ifdef FDT
   53 #include "regdev_if.h"
   54 #endif
   55 
   56 SYSCTL_NODE(_hw, OID_AUTO, regulator, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
   57     "Regulators");
   58 
   59 MALLOC_DEFINE(M_REGULATOR, "regulator", "Regulator framework");
   60 
   61 #define DIV_ROUND_UP(n,d) howmany(n, d)
   62 
   63 /* Forward declarations. */
   64 struct regulator;
   65 struct regnode;
   66 
   67 typedef TAILQ_HEAD(regnode_list, regnode) regnode_list_t;
   68 typedef TAILQ_HEAD(regulator_list, regulator) regulator_list_t;
   69 
   70 /* Default regulator methods. */
   71 static int regnode_method_init(struct regnode *regnode);
   72 static int regnode_method_enable(struct regnode *regnode, bool enable,
   73     int *udelay);
   74 static int regnode_method_status(struct regnode *regnode, int *status);
   75 static int regnode_method_set_voltage(struct regnode *regnode, int min_uvolt,
   76     int max_uvolt, int *udelay);
   77 static int regnode_method_get_voltage(struct regnode *regnode, int *uvolt);
   78 static void regulator_constraint(void *dummy);
   79 static void regulator_shutdown(void *dummy);
   80 
   81 /*
   82  * Regulator controller methods.
   83  */
   84 static regnode_method_t regnode_methods[] = {
   85         REGNODEMETHOD(regnode_init,             regnode_method_init),
   86         REGNODEMETHOD(regnode_enable,           regnode_method_enable),
   87         REGNODEMETHOD(regnode_status,           regnode_method_status),
   88         REGNODEMETHOD(regnode_set_voltage,      regnode_method_set_voltage),
   89         REGNODEMETHOD(regnode_get_voltage,      regnode_method_get_voltage),
   90         REGNODEMETHOD(regnode_check_voltage,    regnode_method_check_voltage),
   91 
   92         REGNODEMETHOD_END
   93 };
   94 DEFINE_CLASS_0(regnode, regnode_class, regnode_methods, 0);
   95 
   96 /*
   97  * Regulator node - basic element for modelling SOC and bard power supply
   98  * chains. Its contains producer data.
   99  */
  100 struct regnode {
  101         KOBJ_FIELDS;
  102 
  103         TAILQ_ENTRY(regnode)    reglist_link;   /* Global list entry */
  104         regulator_list_t        consumers_list; /* Consumers list */
  105 
  106         /* Cache for already resolved names */
  107         struct regnode          *parent;        /* Resolved parent */
  108 
  109         /* Details of this device. */
  110         const char              *name;          /* Globally unique name */
  111         const char              *parent_name;   /* Parent name */
  112 
  113         device_t                pdev;           /* Producer device_t */
  114         void                    *softc;         /* Producer softc */
  115         intptr_t                id;             /* Per producer unique id */
  116 #ifdef FDT
  117          phandle_t              ofw_node;       /* OFW node of regulator */
  118 #endif
  119         int                     flags;          /* REGULATOR_FLAGS_ */
  120         struct sx               lock;           /* Lock for this regulator */
  121         int                     ref_cnt;        /* Reference counter */
  122         int                     enable_cnt;     /* Enabled counter */
  123 
  124         struct regnode_std_param std_param;     /* Standard parameters */
  125 
  126         struct sysctl_ctx_list  sysctl_ctx;
  127 };
  128 
  129 /*
  130  * Per consumer data, information about how a consumer is using a regulator
  131  * node.
  132  * A pointer to this structure is used as a handle in the consumer interface.
  133  */
  134 struct regulator {
  135         device_t                cdev;           /* Consumer device */
  136         struct regnode          *regnode;
  137         TAILQ_ENTRY(regulator)  link;           /* Consumers list entry */
  138 
  139         int                     enable_cnt;
  140         int                     min_uvolt;      /* Requested uvolt range */
  141         int                     max_uvolt;
  142 };
  143 
  144 /*
  145  * Regulator names must be system wide unique.
  146  */
  147 static regnode_list_t regnode_list = TAILQ_HEAD_INITIALIZER(regnode_list);
  148 
  149 static struct sx                regnode_topo_lock;
  150 SX_SYSINIT(regulator_topology, &regnode_topo_lock, "Regulator topology lock");
  151 
  152 #define REG_TOPO_SLOCK()        sx_slock(&regnode_topo_lock)
  153 #define REG_TOPO_XLOCK()        sx_xlock(&regnode_topo_lock)
  154 #define REG_TOPO_UNLOCK()       sx_unlock(&regnode_topo_lock)
  155 #define REG_TOPO_ASSERT()       sx_assert(&regnode_topo_lock, SA_LOCKED)
  156 #define REG_TOPO_XASSERT()      sx_assert(&regnode_topo_lock, SA_XLOCKED)
  157 
  158 #define REGNODE_SLOCK(_sc)      sx_slock(&((_sc)->lock))
  159 #define REGNODE_XLOCK(_sc)      sx_xlock(&((_sc)->lock))
  160 #define REGNODE_UNLOCK(_sc)     sx_unlock(&((_sc)->lock))
  161 
  162 SYSINIT(regulator_constraint, SI_SUB_LAST, SI_ORDER_ANY, regulator_constraint,
  163     NULL);
  164 SYSINIT(regulator_shutdown, SI_SUB_LAST, SI_ORDER_ANY, regulator_shutdown,
  165     NULL);
  166 
  167 static void
  168 regulator_constraint(void *dummy)
  169 {
  170         struct regnode *entry;
  171         int rv;
  172 
  173         REG_TOPO_SLOCK();
  174         TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
  175                 rv = regnode_set_constraint(entry);
  176                 if (rv != 0 && bootverbose)
  177                         printf("regulator: setting constraint on %s failed (%d)\n",
  178                             entry->name, rv);
  179         }
  180         REG_TOPO_UNLOCK();
  181 }
  182 
  183 /*
  184  * Disable unused regulator
  185  * We run this function at SI_SUB_LAST which mean that every driver that needs
  186  * regulator should have already enable them.
  187  * All the remaining regulators should be those left enabled by the bootloader
  188  * or enable by default by the PMIC.
  189  */
  190 static void
  191 regulator_shutdown(void *dummy)
  192 {
  193         struct regnode *entry;
  194         int status, ret;
  195         int disable = 1;
  196 
  197         TUNABLE_INT_FETCH("hw.regulator.disable_unused", &disable);
  198         if (!disable)
  199                 return;
  200         REG_TOPO_SLOCK();
  201 
  202         if (bootverbose)
  203                 printf("regulator: shutting down unused regulators\n");
  204         TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
  205                 if (!entry->std_param.always_on) {
  206                         ret = regnode_status(entry, &status);
  207                         if (ret == 0 && status == REGULATOR_STATUS_ENABLED) {
  208                                 if (bootverbose)
  209                                         printf("regulator: shutting down %s... ",
  210                                             entry->name);
  211                                 ret = regnode_stop(entry, 0);
  212                                 if (bootverbose) {
  213                                         /*
  214                                          * Call out busy in particular, here,
  215                                          * because it's not unexpected to fail
  216                                          * shutdown if the regulator is simply
  217                                          * in-use.
  218                                          */
  219                                         if (ret == EBUSY)
  220                                                 printf("busy\n");
  221                                         else if (ret != 0)
  222                                                 printf("error (%d)\n", ret);
  223                                         else
  224                                                 printf("ok\n");
  225                                 }
  226                         }
  227                 }
  228         }
  229         REG_TOPO_UNLOCK();
  230 }
  231 
  232 /*
  233  * sysctl handler
  234  */
  235 static int
  236 regnode_uvolt_sysctl(SYSCTL_HANDLER_ARGS)
  237 {
  238         struct regnode *regnode = arg1;
  239         int rv, uvolt;
  240 
  241         if (regnode->std_param.min_uvolt == regnode->std_param.max_uvolt) {
  242                 uvolt = regnode->std_param.min_uvolt;
  243         } else {
  244                 REG_TOPO_SLOCK();
  245                 if ((rv = regnode_get_voltage(regnode, &uvolt)) != 0) {
  246                         REG_TOPO_UNLOCK();
  247                         return (rv);
  248                 }
  249                 REG_TOPO_UNLOCK();
  250         }
  251 
  252         return sysctl_handle_int(oidp, &uvolt, sizeof(uvolt), req);
  253 }
  254 
  255 /* ----------------------------------------------------------------------------
  256  *
  257  * Default regulator methods for base class.
  258  *
  259  */
  260 static int
  261 regnode_method_init(struct regnode *regnode)
  262 {
  263 
  264         return (0);
  265 }
  266 
  267 static int
  268 regnode_method_enable(struct regnode *regnode, bool enable, int *udelay)
  269 {
  270 
  271         if (!enable)
  272                 return (ENXIO);
  273 
  274         *udelay = 0;
  275         return (0);
  276 }
  277 
  278 static int
  279 regnode_method_status(struct regnode *regnode, int *status)
  280 {
  281         *status = REGULATOR_STATUS_ENABLED;
  282         return (0);
  283 }
  284 
  285 static int
  286 regnode_method_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt,
  287     int *udelay)
  288 {
  289 
  290         if ((min_uvolt > regnode->std_param.max_uvolt) ||
  291             (max_uvolt < regnode->std_param.min_uvolt))
  292                 return (ERANGE);
  293         *udelay = 0;
  294         return (0);
  295 }
  296 
  297 static int
  298 regnode_method_get_voltage(struct regnode *regnode, int *uvolt)
  299 {
  300 
  301         *uvolt = regnode->std_param.min_uvolt +
  302             (regnode->std_param.max_uvolt - regnode->std_param.min_uvolt) / 2;
  303         return (0);
  304 }
  305 
  306 int
  307 regnode_method_check_voltage(struct regnode *regnode, int uvolt)
  308 {
  309 
  310         if ((uvolt > regnode->std_param.max_uvolt) ||
  311             (uvolt < regnode->std_param.min_uvolt))
  312                 return (ERANGE);
  313         return (0);
  314 }
  315 
  316 /* ----------------------------------------------------------------------------
  317  *
  318  * Internal functions.
  319  *
  320  */
  321 
  322 static struct regnode *
  323 regnode_find_by_name(const char *name)
  324 {
  325         struct regnode *entry;
  326 
  327         REG_TOPO_ASSERT();
  328 
  329         TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
  330                 if (strcmp(entry->name, name) == 0)
  331                         return (entry);
  332         }
  333         return (NULL);
  334 }
  335 
  336 static struct regnode *
  337 regnode_find_by_id(device_t dev, intptr_t id)
  338 {
  339         struct regnode *entry;
  340 
  341         REG_TOPO_ASSERT();
  342 
  343         TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
  344                 if ((entry->pdev == dev) && (entry->id ==  id))
  345                         return (entry);
  346         }
  347 
  348         return (NULL);
  349 }
  350 
  351 /*
  352  * Create and initialize regulator object, but do not register it.
  353  */
  354 struct regnode *
  355 regnode_create(device_t pdev, regnode_class_t regnode_class,
  356     struct regnode_init_def *def)
  357 {
  358         struct regnode *regnode;
  359         struct sysctl_oid *regnode_oid;
  360 
  361         KASSERT(def->name != NULL, ("regulator name is NULL"));
  362         KASSERT(def->name[0] != '\0', ("regulator name is empty"));
  363 
  364         REG_TOPO_SLOCK();
  365         if (regnode_find_by_name(def->name) != NULL)
  366                 panic("Duplicated regulator registration: %s\n", def->name);
  367         REG_TOPO_UNLOCK();
  368 
  369         /* Create object and initialize it. */
  370         regnode = malloc(sizeof(struct regnode), M_REGULATOR,
  371             M_WAITOK | M_ZERO);
  372         kobj_init((kobj_t)regnode, (kobj_class_t)regnode_class);
  373         sx_init(&regnode->lock, "Regulator node lock");
  374 
  375         /* Allocate softc if required. */
  376         if (regnode_class->size > 0) {
  377                 regnode->softc = malloc(regnode_class->size, M_REGULATOR,
  378                     M_WAITOK | M_ZERO);
  379         }
  380 
  381 
  382         /* Copy all strings unless they're flagged as static. */
  383         if (def->flags & REGULATOR_FLAGS_STATIC) {
  384                 regnode->name = def->name;
  385                 regnode->parent_name = def->parent_name;
  386         } else {
  387                 regnode->name = strdup(def->name, M_REGULATOR);
  388                 if (def->parent_name != NULL)
  389                         regnode->parent_name = strdup(def->parent_name,
  390                             M_REGULATOR);
  391         }
  392 
  393         /* Rest of init. */
  394         TAILQ_INIT(&regnode->consumers_list);
  395         regnode->id = def->id;
  396         regnode->pdev = pdev;
  397         regnode->flags = def->flags;
  398         regnode->parent = NULL;
  399         regnode->std_param = def->std_param;
  400 #ifdef FDT
  401         regnode->ofw_node = def->ofw_node;
  402 #endif
  403 
  404         sysctl_ctx_init(&regnode->sysctl_ctx);
  405         regnode_oid = SYSCTL_ADD_NODE(&regnode->sysctl_ctx,
  406             SYSCTL_STATIC_CHILDREN(_hw_regulator),
  407             OID_AUTO, regnode->name,
  408             CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "A regulator node");
  409 
  410         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  411             SYSCTL_CHILDREN(regnode_oid),
  412             OID_AUTO, "min_uvolt",
  413             CTLFLAG_RD, &regnode->std_param.min_uvolt, 0,
  414             "Minimal voltage (in uV)");
  415         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  416             SYSCTL_CHILDREN(regnode_oid),
  417             OID_AUTO, "max_uvolt",
  418             CTLFLAG_RD, &regnode->std_param.max_uvolt, 0,
  419             "Maximal voltage (in uV)");
  420         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  421             SYSCTL_CHILDREN(regnode_oid),
  422             OID_AUTO, "min_uamp",
  423             CTLFLAG_RD, &regnode->std_param.min_uamp, 0,
  424             "Minimal amperage (in uA)");
  425         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  426             SYSCTL_CHILDREN(regnode_oid),
  427             OID_AUTO, "max_uamp",
  428             CTLFLAG_RD, &regnode->std_param.max_uamp, 0,
  429             "Maximal amperage (in uA)");
  430         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  431             SYSCTL_CHILDREN(regnode_oid),
  432             OID_AUTO, "ramp_delay",
  433             CTLFLAG_RD, &regnode->std_param.ramp_delay, 0,
  434             "Ramp delay (in uV/us)");
  435         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  436             SYSCTL_CHILDREN(regnode_oid),
  437             OID_AUTO, "enable_delay",
  438             CTLFLAG_RD, &regnode->std_param.enable_delay, 0,
  439             "Enable delay (in us)");
  440         SYSCTL_ADD_INT(&regnode->sysctl_ctx,
  441             SYSCTL_CHILDREN(regnode_oid),
  442             OID_AUTO, "enable_cnt",
  443             CTLFLAG_RD, &regnode->enable_cnt, 0,
  444             "The regulator enable counter");
  445         SYSCTL_ADD_U8(&regnode->sysctl_ctx,
  446             SYSCTL_CHILDREN(regnode_oid),
  447             OID_AUTO, "boot_on",
  448             CTLFLAG_RD, (uint8_t *) &regnode->std_param.boot_on, 0,
  449             "Is enabled on boot");
  450         SYSCTL_ADD_U8(&regnode->sysctl_ctx,
  451             SYSCTL_CHILDREN(regnode_oid),
  452             OID_AUTO, "always_on",
  453             CTLFLAG_RD, (uint8_t *)&regnode->std_param.always_on, 0,
  454             "Is always enabled");
  455 
  456         SYSCTL_ADD_PROC(&regnode->sysctl_ctx,
  457             SYSCTL_CHILDREN(regnode_oid),
  458             OID_AUTO, "uvolt",
  459             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
  460             regnode, 0, regnode_uvolt_sysctl,
  461             "I",
  462             "Current voltage (in uV)");
  463 
  464         return (regnode);
  465 }
  466 
  467 /* Register regulator object. */
  468 struct regnode *
  469 regnode_register(struct regnode *regnode)
  470 {
  471         int rv;
  472 
  473 #ifdef FDT
  474         if (regnode->ofw_node <= 0)
  475                 regnode->ofw_node = ofw_bus_get_node(regnode->pdev);
  476         if (regnode->ofw_node <= 0)
  477                 return (NULL);
  478 #endif
  479 
  480         rv = REGNODE_INIT(regnode);
  481         if (rv != 0) {
  482                 printf("REGNODE_INIT failed: %d\n", rv);
  483                 return (NULL);
  484         }
  485 
  486         REG_TOPO_XLOCK();
  487         TAILQ_INSERT_TAIL(&regnode_list, regnode, reglist_link);
  488         REG_TOPO_UNLOCK();
  489 #ifdef FDT
  490         OF_device_register_xref(OF_xref_from_node(regnode->ofw_node),
  491             regnode->pdev);
  492 #endif
  493         return (regnode);
  494 }
  495 
  496 static int
  497 regnode_resolve_parent(struct regnode *regnode)
  498 {
  499 
  500         /* All ready resolved or no parent? */
  501         if ((regnode->parent != NULL) ||
  502             (regnode->parent_name == NULL))
  503                 return (0);
  504 
  505         regnode->parent = regnode_find_by_name(regnode->parent_name);
  506         if (regnode->parent == NULL)
  507                 return (ENODEV);
  508         return (0);
  509 }
  510 
  511 static void
  512 regnode_delay(int usec)
  513 {
  514         int ticks;
  515 
  516         if (usec == 0)
  517                 return;
  518         ticks = (usec * hz + 999999) / 1000000;
  519 
  520         if (cold || ticks < 2)
  521                 DELAY(usec);
  522         else
  523                 pause("REGULATOR", ticks);
  524 }
  525 
  526 /* --------------------------------------------------------------------------
  527  *
  528  * Regulator providers interface
  529  *
  530  */
  531 
  532 const char *
  533 regnode_get_name(struct regnode *regnode)
  534 {
  535 
  536         return (regnode->name);
  537 }
  538 
  539 const char *
  540 regnode_get_parent_name(struct regnode *regnode)
  541 {
  542 
  543         return (regnode->parent_name);
  544 }
  545 
  546 int
  547 regnode_get_flags(struct regnode *regnode)
  548 {
  549 
  550         return (regnode->flags);
  551 }
  552 
  553 void *
  554 regnode_get_softc(struct regnode *regnode)
  555 {
  556 
  557         return (regnode->softc);
  558 }
  559 
  560 device_t
  561 regnode_get_device(struct regnode *regnode)
  562 {
  563 
  564         return (regnode->pdev);
  565 }
  566 
  567 struct regnode_std_param *regnode_get_stdparam(struct regnode *regnode)
  568 {
  569 
  570         return (&regnode->std_param);
  571 }
  572 
  573 void regnode_topo_unlock(void)
  574 {
  575 
  576         REG_TOPO_UNLOCK();
  577 }
  578 
  579 void regnode_topo_xlock(void)
  580 {
  581 
  582         REG_TOPO_XLOCK();
  583 }
  584 
  585 void regnode_topo_slock(void)
  586 {
  587 
  588         REG_TOPO_SLOCK();
  589 }
  590 
  591 
  592 /* --------------------------------------------------------------------------
  593  *
  594  * Real consumers executive
  595  *
  596  */
  597 struct regnode *
  598 regnode_get_parent(struct regnode *regnode)
  599 {
  600         int rv;
  601 
  602         REG_TOPO_ASSERT();
  603 
  604         rv = regnode_resolve_parent(regnode);
  605         if (rv != 0)
  606                 return (NULL);
  607 
  608         return (regnode->parent);
  609 }
  610 
  611 /*
  612  * Enable regulator.
  613  */
  614 int
  615 regnode_enable(struct regnode *regnode)
  616 {
  617         int udelay;
  618         int rv;
  619 
  620         REG_TOPO_ASSERT();
  621 
  622         /* Enable regulator for each node in chain, starting from source. */
  623         rv = regnode_resolve_parent(regnode);
  624         if (rv != 0)
  625                 return (rv);
  626         if (regnode->parent != NULL) {
  627                 rv = regnode_enable(regnode->parent);
  628                 if (rv != 0)
  629                         return (rv);
  630         }
  631 
  632         /* Handle this node. */
  633         REGNODE_XLOCK(regnode);
  634         if (regnode->enable_cnt == 0) {
  635                 rv = REGNODE_ENABLE(regnode, true, &udelay);
  636                 if (rv != 0) {
  637                         REGNODE_UNLOCK(regnode);
  638                         return (rv);
  639                 }
  640                 regnode_delay(udelay);
  641         }
  642         regnode->enable_cnt++;
  643         REGNODE_UNLOCK(regnode);
  644         return (0);
  645 }
  646 
  647 /*
  648  * Disable regulator.
  649  */
  650 int
  651 regnode_disable(struct regnode *regnode)
  652 {
  653         int udelay;
  654         int rv;
  655 
  656         REG_TOPO_ASSERT();
  657         rv = 0;
  658 
  659         REGNODE_XLOCK(regnode);
  660         /* Disable regulator for each node in chain, starting from consumer. */
  661         if (regnode->enable_cnt == 1 &&
  662             (regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0 &&
  663             !regnode->std_param.always_on) {
  664                 rv = REGNODE_ENABLE(regnode, false, &udelay);
  665                 if (rv != 0) {
  666                         REGNODE_UNLOCK(regnode);
  667                         return (rv);
  668                 }
  669                 regnode_delay(udelay);
  670         }
  671         regnode->enable_cnt--;
  672         REGNODE_UNLOCK(regnode);
  673 
  674         rv = regnode_resolve_parent(regnode);
  675         if (rv != 0)
  676                 return (rv);
  677         if (regnode->parent != NULL)
  678                 rv = regnode_disable(regnode->parent);
  679         return (rv);
  680 }
  681 
  682 /*
  683  * Stop regulator.
  684  */
  685 int
  686 regnode_stop(struct regnode *regnode, int depth)
  687 {
  688         int udelay;
  689         int rv;
  690 
  691         REG_TOPO_ASSERT();
  692         rv = 0;
  693 
  694         REGNODE_XLOCK(regnode);
  695         /* The first node must not be enabled. */
  696         if ((regnode->enable_cnt != 0) && (depth == 0)) {
  697                 REGNODE_UNLOCK(regnode);
  698                 return (EBUSY);
  699         }
  700         /* Disable regulator for each node in chain, starting from consumer */
  701         if ((regnode->enable_cnt == 0) &&
  702             ((regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0)) {
  703                 rv = REGNODE_STOP(regnode, &udelay);
  704                 if (rv != 0) {
  705                         REGNODE_UNLOCK(regnode);
  706                         return (rv);
  707                 }
  708                 regnode_delay(udelay);
  709         }
  710         REGNODE_UNLOCK(regnode);
  711 
  712         rv = regnode_resolve_parent(regnode);
  713         if (rv != 0)
  714                 return (rv);
  715         if (regnode->parent != NULL && regnode->parent->enable_cnt == 0)
  716                 rv = regnode_stop(regnode->parent, depth + 1);
  717         return (rv);
  718 }
  719 
  720 /*
  721  * Get regulator status. (REGULATOR_STATUS_*)
  722  */
  723 int
  724 regnode_status(struct regnode *regnode, int *status)
  725 {
  726         int rv;
  727 
  728         REG_TOPO_ASSERT();
  729 
  730         REGNODE_XLOCK(regnode);
  731         rv = REGNODE_STATUS(regnode, status);
  732         REGNODE_UNLOCK(regnode);
  733         return (rv);
  734 }
  735 
  736 /*
  737  * Get actual regulator voltage.
  738  */
  739 int
  740 regnode_get_voltage(struct regnode *regnode, int *uvolt)
  741 {
  742         int rv;
  743 
  744         REG_TOPO_ASSERT();
  745 
  746         REGNODE_XLOCK(regnode);
  747         rv = REGNODE_GET_VOLTAGE(regnode, uvolt);
  748         REGNODE_UNLOCK(regnode);
  749 
  750         /* Pass call into parent, if regulator is in bypass mode. */
  751         if (rv == ENOENT) {
  752                 rv = regnode_resolve_parent(regnode);
  753                 if (rv != 0)
  754                         return (rv);
  755                 if (regnode->parent != NULL)
  756                         rv = regnode_get_voltage(regnode->parent, uvolt);
  757 
  758         }
  759         return (rv);
  760 }
  761 
  762 /*
  763  * Set regulator voltage.
  764  */
  765 int
  766 regnode_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt)
  767 {
  768         int udelay;
  769         int rv;
  770 
  771         REG_TOPO_ASSERT();
  772 
  773         REGNODE_XLOCK(regnode);
  774 
  775         rv = REGNODE_SET_VOLTAGE(regnode, min_uvolt, max_uvolt, &udelay);
  776         if (rv == 0)
  777                 regnode_delay(udelay);
  778         REGNODE_UNLOCK(regnode);
  779         return (rv);
  780 }
  781 
  782 /*
  783  * Consumer variant of regnode_set_voltage().
  784  */
  785 static int
  786 regnode_set_voltage_checked(struct regnode *regnode, struct regulator *reg,
  787     int min_uvolt, int max_uvolt)
  788 {
  789         int udelay;
  790         int all_max_uvolt;
  791         int all_min_uvolt;
  792         struct regulator *tmp;
  793         int rv;
  794 
  795         REG_TOPO_ASSERT();
  796 
  797         REGNODE_XLOCK(regnode);
  798         /* Return error if requested range is outside of regulator range. */
  799         if ((min_uvolt > regnode->std_param.max_uvolt) ||
  800             (max_uvolt < regnode->std_param.min_uvolt)) {
  801                 REGNODE_UNLOCK(regnode);
  802                 return (ERANGE);
  803         }
  804 
  805         /* Get actual voltage range for all consumers. */
  806         all_min_uvolt = regnode->std_param.min_uvolt;
  807         all_max_uvolt = regnode->std_param.max_uvolt;
  808         TAILQ_FOREACH(tmp, &regnode->consumers_list, link) {
  809                 /* Don't take requestor in account. */
  810                 if (tmp == reg)
  811                         continue;
  812                 if (all_min_uvolt < tmp->min_uvolt)
  813                         all_min_uvolt = tmp->min_uvolt;
  814                 if (all_max_uvolt > tmp->max_uvolt)
  815                         all_max_uvolt = tmp->max_uvolt;
  816         }
  817 
  818         /* Test if request fits to actual contract. */
  819         if ((min_uvolt > all_max_uvolt) ||
  820             (max_uvolt < all_min_uvolt)) {
  821                 REGNODE_UNLOCK(regnode);
  822                 return (ERANGE);
  823         }
  824 
  825         /* Adjust new range.*/
  826         if (min_uvolt < all_min_uvolt)
  827                 min_uvolt = all_min_uvolt;
  828         if (max_uvolt > all_max_uvolt)
  829                 max_uvolt = all_max_uvolt;
  830 
  831         rv = REGNODE_SET_VOLTAGE(regnode, min_uvolt, max_uvolt, &udelay);
  832         regnode_delay(udelay);
  833         REGNODE_UNLOCK(regnode);
  834         return (rv);
  835 }
  836 
  837 int
  838 regnode_set_constraint(struct regnode *regnode)
  839 {
  840         int status, rv, uvolt;
  841 
  842         if (regnode->std_param.boot_on != true &&
  843             regnode->std_param.always_on != true)
  844                 return (0);
  845 
  846         rv = regnode_status(regnode, &status);
  847         if (rv != 0) {
  848                 if (bootverbose)
  849                         printf("Cannot get regulator status for %s\n",
  850                             regnode_get_name(regnode));
  851                 return (rv);
  852         }
  853 
  854         if (status == REGULATOR_STATUS_ENABLED)
  855                 return (0);
  856 
  857         rv = regnode_get_voltage(regnode, &uvolt);
  858         if (rv != 0) {
  859                 if (bootverbose)
  860                         printf("Cannot get regulator voltage for %s\n",
  861                             regnode_get_name(regnode));
  862                 return (rv);
  863         }
  864 
  865         if (uvolt < regnode->std_param.min_uvolt ||
  866           uvolt > regnode->std_param.max_uvolt) {
  867                 if (bootverbose)
  868                         printf("Regulator %s current voltage %d is not in the"
  869                             " acceptable range : %d<->%d\n",
  870                             regnode_get_name(regnode),
  871                             uvolt, regnode->std_param.min_uvolt,
  872                             regnode->std_param.max_uvolt);
  873                 return (ERANGE);
  874         }
  875 
  876         rv = regnode_enable(regnode);
  877         if (rv != 0) {
  878                 if (bootverbose)
  879                         printf("Cannot enable regulator %s\n",
  880                             regnode_get_name(regnode));
  881                 return (rv);
  882         }
  883 
  884         return (0);
  885 }
  886 
  887 #ifdef FDT
  888 phandle_t
  889 regnode_get_ofw_node(struct regnode *regnode)
  890 {
  891 
  892         return (regnode->ofw_node);
  893 }
  894 #endif
  895 
  896 /* --------------------------------------------------------------------------
  897  *
  898  * Regulator consumers interface.
  899  *
  900  */
  901 /* Helper function for regulator_get*() */
  902 static regulator_t
  903 regulator_create(struct regnode *regnode, device_t cdev)
  904 {
  905         struct regulator *reg;
  906 
  907         REG_TOPO_ASSERT();
  908 
  909         reg =  malloc(sizeof(struct regulator), M_REGULATOR,
  910             M_WAITOK | M_ZERO);
  911         reg->cdev = cdev;
  912         reg->regnode = regnode;
  913         reg->enable_cnt = 0;
  914 
  915         REGNODE_XLOCK(regnode);
  916         regnode->ref_cnt++;
  917         TAILQ_INSERT_TAIL(&regnode->consumers_list, reg, link);
  918         reg ->min_uvolt = regnode->std_param.min_uvolt;
  919         reg ->max_uvolt = regnode->std_param.max_uvolt;
  920         REGNODE_UNLOCK(regnode);
  921 
  922         return (reg);
  923 }
  924 
  925 int
  926 regulator_enable(regulator_t reg)
  927 {
  928         int rv;
  929         struct regnode *regnode;
  930 
  931         regnode = reg->regnode;
  932         KASSERT(regnode->ref_cnt > 0,
  933            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
  934         REG_TOPO_SLOCK();
  935         rv = regnode_enable(regnode);
  936         if (rv == 0)
  937                 reg->enable_cnt++;
  938         REG_TOPO_UNLOCK();
  939         return (rv);
  940 }
  941 
  942 int
  943 regulator_disable(regulator_t reg)
  944 {
  945         int rv;
  946         struct regnode *regnode;
  947 
  948         regnode = reg->regnode;
  949         KASSERT(regnode->ref_cnt > 0,
  950            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
  951         KASSERT(reg->enable_cnt > 0,
  952            ("Attempt to disable already disabled regulator: %s\n",
  953            regnode->name));
  954         REG_TOPO_SLOCK();
  955         rv = regnode_disable(regnode);
  956         if (rv == 0)
  957                 reg->enable_cnt--;
  958         REG_TOPO_UNLOCK();
  959         return (rv);
  960 }
  961 
  962 int
  963 regulator_stop(regulator_t reg)
  964 {
  965         int rv;
  966         struct regnode *regnode;
  967 
  968         regnode = reg->regnode;
  969         KASSERT(regnode->ref_cnt > 0,
  970            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
  971         KASSERT(reg->enable_cnt == 0,
  972            ("Attempt to stop already enabled regulator: %s\n", regnode->name));
  973 
  974         REG_TOPO_SLOCK();
  975         rv = regnode_stop(regnode, 0);
  976         REG_TOPO_UNLOCK();
  977         return (rv);
  978 }
  979 
  980 int
  981 regulator_status(regulator_t reg, int *status)
  982 {
  983         int rv;
  984         struct regnode *regnode;
  985 
  986         regnode = reg->regnode;
  987         KASSERT(regnode->ref_cnt > 0,
  988            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
  989 
  990         if (reg->enable_cnt == 0) {
  991                 *status = 0;
  992                 return (0);
  993         }
  994         REG_TOPO_SLOCK();
  995         rv = regnode_status(regnode, status);
  996         REG_TOPO_UNLOCK();
  997         return (rv);
  998 }
  999 
 1000 int
 1001 regulator_get_voltage(regulator_t reg, int *uvolt)
 1002 {
 1003         int rv;
 1004         struct regnode *regnode;
 1005 
 1006         regnode = reg->regnode;
 1007         KASSERT(regnode->ref_cnt > 0,
 1008            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
 1009 
 1010         REG_TOPO_SLOCK();
 1011         rv = regnode_get_voltage(regnode, uvolt);
 1012         REG_TOPO_UNLOCK();
 1013         return (rv);
 1014 }
 1015 
 1016 int
 1017 regulator_set_voltage(regulator_t reg, int min_uvolt, int max_uvolt)
 1018 {
 1019         struct regnode *regnode;
 1020         int rv;
 1021 
 1022         regnode = reg->regnode;
 1023         KASSERT(regnode->ref_cnt > 0,
 1024            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
 1025 
 1026         REG_TOPO_SLOCK();
 1027 
 1028         rv = regnode_set_voltage_checked(regnode, reg, min_uvolt, max_uvolt);
 1029         if (rv == 0) {
 1030                 reg->min_uvolt = min_uvolt;
 1031                 reg->max_uvolt = max_uvolt;
 1032         }
 1033         REG_TOPO_UNLOCK();
 1034         return (rv);
 1035 }
 1036 
 1037 int
 1038 regulator_check_voltage(regulator_t reg, int uvolt)
 1039 {
 1040         int rv;
 1041         struct regnode *regnode;
 1042 
 1043         regnode = reg->regnode;
 1044         KASSERT(regnode->ref_cnt > 0,
 1045            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
 1046 
 1047         REG_TOPO_SLOCK();
 1048         rv = REGNODE_CHECK_VOLTAGE(regnode, uvolt);
 1049         REG_TOPO_UNLOCK();
 1050         return (rv);
 1051 }
 1052 
 1053 const char *
 1054 regulator_get_name(regulator_t reg)
 1055 {
 1056         struct regnode *regnode;
 1057 
 1058         regnode = reg->regnode;
 1059         KASSERT(regnode->ref_cnt > 0,
 1060            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
 1061         return (regnode->name);
 1062 }
 1063 
 1064 int
 1065 regulator_get_by_name(device_t cdev, const char *name, regulator_t *reg)
 1066 {
 1067         struct regnode *regnode;
 1068 
 1069         REG_TOPO_SLOCK();
 1070         regnode = regnode_find_by_name(name);
 1071         if (regnode == NULL) {
 1072                 REG_TOPO_UNLOCK();
 1073                 return (ENODEV);
 1074         }
 1075         *reg = regulator_create(regnode, cdev);
 1076         REG_TOPO_UNLOCK();
 1077         return (0);
 1078 }
 1079 
 1080 int
 1081 regulator_get_by_id(device_t cdev, device_t pdev, intptr_t id, regulator_t *reg)
 1082 {
 1083         struct regnode *regnode;
 1084 
 1085         REG_TOPO_SLOCK();
 1086 
 1087         regnode = regnode_find_by_id(pdev, id);
 1088         if (regnode == NULL) {
 1089                 REG_TOPO_UNLOCK();
 1090                 return (ENODEV);
 1091         }
 1092         *reg = regulator_create(regnode, cdev);
 1093         REG_TOPO_UNLOCK();
 1094 
 1095         return (0);
 1096 }
 1097 
 1098 int
 1099 regulator_release(regulator_t reg)
 1100 {
 1101         struct regnode *regnode;
 1102 
 1103         regnode = reg->regnode;
 1104         KASSERT(regnode->ref_cnt > 0,
 1105            ("Attempt to access unreferenced regulator: %s\n", regnode->name));
 1106         REG_TOPO_SLOCK();
 1107         while (reg->enable_cnt > 0) {
 1108                 regnode_disable(regnode);
 1109                 reg->enable_cnt--;
 1110         }
 1111         REGNODE_XLOCK(regnode);
 1112         TAILQ_REMOVE(&regnode->consumers_list, reg, link);
 1113         regnode->ref_cnt--;
 1114         REGNODE_UNLOCK(regnode);
 1115         REG_TOPO_UNLOCK();
 1116 
 1117         free(reg, M_REGULATOR);
 1118         return (0);
 1119 }
 1120 
 1121 #ifdef FDT
 1122 /* Default DT mapper. */
 1123 int
 1124 regdev_default_ofw_map(device_t dev, phandle_t  xref, int ncells,
 1125     pcell_t *cells, intptr_t *id)
 1126 {
 1127         if (ncells == 0)
 1128                 *id = 1;
 1129         else if (ncells == 1)
 1130                 *id = cells[0];
 1131         else
 1132                 return  (ERANGE);
 1133 
 1134         return (0);
 1135 }
 1136 
 1137 int
 1138 regulator_parse_ofw_stdparam(device_t pdev, phandle_t node,
 1139     struct regnode_init_def *def)
 1140 {
 1141         phandle_t supply_xref;
 1142         struct regnode_std_param *par;
 1143         int rv;
 1144 
 1145         par = &def->std_param;
 1146         rv = OF_getprop_alloc(node, "regulator-name",
 1147             (void **)&def->name);
 1148         if (rv <= 0) {
 1149                 device_printf(pdev, "%s: Missing regulator name\n",
 1150                  __func__);
 1151                 return (ENXIO);
 1152         }
 1153 
 1154         rv = OF_getencprop(node, "regulator-min-microvolt", &par->min_uvolt,
 1155             sizeof(par->min_uvolt));
 1156         if (rv <= 0)
 1157                 par->min_uvolt = 0;
 1158 
 1159         rv = OF_getencprop(node, "regulator-max-microvolt", &par->max_uvolt,
 1160             sizeof(par->max_uvolt));
 1161         if (rv <= 0)
 1162                 par->max_uvolt = 0;
 1163 
 1164         rv = OF_getencprop(node, "regulator-min-microamp", &par->min_uamp,
 1165             sizeof(par->min_uamp));
 1166         if (rv <= 0)
 1167                 par->min_uamp = 0;
 1168 
 1169         rv = OF_getencprop(node, "regulator-max-microamp", &par->max_uamp,
 1170             sizeof(par->max_uamp));
 1171         if (rv <= 0)
 1172                 par->max_uamp = 0;
 1173 
 1174         rv = OF_getencprop(node, "regulator-ramp-delay", &par->ramp_delay,
 1175             sizeof(par->ramp_delay));
 1176         if (rv <= 0)
 1177                 par->ramp_delay = 0;
 1178 
 1179         rv = OF_getencprop(node, "regulator-enable-ramp-delay",
 1180             &par->enable_delay, sizeof(par->enable_delay));
 1181         if (rv <= 0)
 1182                 par->enable_delay = 0;
 1183 
 1184         if (OF_hasprop(node, "regulator-boot-on"))
 1185                 par->boot_on = true;
 1186 
 1187         if (OF_hasprop(node, "regulator-always-on"))
 1188                 par->always_on = true;
 1189 
 1190         if (OF_hasprop(node, "enable-active-high"))
 1191                 par->enable_active_high = 1;
 1192 
 1193         rv = OF_getencprop(node, "vin-supply", &supply_xref,
 1194             sizeof(supply_xref));
 1195         if (rv >=  0) {
 1196                 rv = OF_getprop_alloc(supply_xref, "regulator-name",
 1197                     (void **)&def->parent_name);
 1198                 if (rv <= 0)
 1199                         def->parent_name = NULL;
 1200         }
 1201         return (0);
 1202 }
 1203 
 1204 int
 1205 regulator_get_by_ofw_property(device_t cdev, phandle_t cnode, char *name,
 1206     regulator_t *reg)
 1207 {
 1208         phandle_t *cells;
 1209         device_t regdev;
 1210         int ncells, rv;
 1211         intptr_t id;
 1212 
 1213         *reg = NULL;
 1214 
 1215         if (cnode <= 0)
 1216                 cnode = ofw_bus_get_node(cdev);
 1217         if (cnode <= 0) {
 1218                 device_printf(cdev, "%s called on not ofw based device\n",
 1219                  __func__);
 1220                 return (ENXIO);
 1221         }
 1222 
 1223         cells = NULL;
 1224         ncells = OF_getencprop_alloc_multi(cnode, name, sizeof(*cells),
 1225             (void **)&cells);
 1226         if (ncells <= 0)
 1227                 return (ENOENT);
 1228 
 1229         /* Translate xref to device */
 1230         regdev = OF_device_from_xref(cells[0]);
 1231         if (regdev == NULL) {
 1232                 OF_prop_free(cells);
 1233                 return (ENODEV);
 1234         }
 1235 
 1236         /* Map regulator to number */
 1237         rv = REGDEV_MAP(regdev, cells[0], ncells - 1, cells + 1, &id);
 1238         OF_prop_free(cells);
 1239         if (rv != 0)
 1240                 return (rv);
 1241         return (regulator_get_by_id(cdev, regdev, id, reg));
 1242 }
 1243 #endif
 1244 
 1245 /* --------------------------------------------------------------------------
 1246  *
 1247  * Regulator utility functions.
 1248  *
 1249  */
 1250 
 1251 /* Convert raw selector value to real voltage */
 1252 int
 1253 regulator_range_sel8_to_volt(struct regulator_range *ranges, int nranges,
 1254    uint8_t sel, int *volt)
 1255 {
 1256         struct regulator_range *range;
 1257         int i;
 1258 
 1259         if (nranges == 0)
 1260                 panic("Voltage regulator have zero ranges\n");
 1261 
 1262         for (i = 0; i < nranges ; i++) {
 1263                 range = ranges  + i;
 1264 
 1265                 if (!(sel >= range->min_sel &&
 1266                       sel <= range->max_sel))
 1267                         continue;
 1268 
 1269                 sel -= range->min_sel;
 1270 
 1271                 *volt = range->min_uvolt + sel * range->step_uvolt;
 1272                 return (0);
 1273         }
 1274 
 1275         return (ERANGE);
 1276 }
 1277 
 1278 int
 1279 regulator_range_volt_to_sel8(struct regulator_range *ranges, int nranges,
 1280     int min_uvolt, int max_uvolt, uint8_t *out_sel)
 1281 {
 1282         struct regulator_range *range;
 1283         uint8_t sel;
 1284         int uvolt;
 1285         int rv, i;
 1286 
 1287         if (nranges == 0)
 1288                 panic("Voltage regulator have zero ranges\n");
 1289 
 1290         for (i = 0; i < nranges; i++) {
 1291                 range = ranges  + i;
 1292                 uvolt = range->min_uvolt +
 1293                     (range->max_sel - range->min_sel) * range->step_uvolt;
 1294 
 1295                 if ((min_uvolt > uvolt) ||
 1296                     (max_uvolt < range->min_uvolt))
 1297                         continue;
 1298 
 1299                 if (min_uvolt <= range->min_uvolt)
 1300                         min_uvolt = range->min_uvolt;
 1301 
 1302                 /* if step == 0 -> fixed voltage range. */
 1303                 if (range->step_uvolt == 0)
 1304                         sel = 0;
 1305                 else
 1306                         sel = DIV_ROUND_UP(min_uvolt - range->min_uvolt,
 1307                            range->step_uvolt);
 1308 
 1309 
 1310                 sel += range->min_sel;
 1311 
 1312                 break;
 1313         }
 1314 
 1315         if (i >= nranges)
 1316                 return (ERANGE);
 1317 
 1318         /* Verify new settings. */
 1319         rv = regulator_range_sel8_to_volt(ranges, nranges, sel, &uvolt);
 1320         if (rv != 0)
 1321                 return (rv);
 1322         if ((uvolt < min_uvolt) || (uvolt > max_uvolt))
 1323                 return (ERANGE);
 1324 
 1325         *out_sel = sel;
 1326         return (0);
 1327 }

Cache object: 88957e9ec0622a4c2aeddba3afc6249e


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