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/fdt/fdt_pinctrl.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 (c) 2014 Ian Lepore <ian@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  * $FreeBSD$
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 #include <sys/param.h>
   31 
   32 #include <dev/ofw/ofw_bus.h>
   33 #include <dev/ofw/ofw_bus_subr.h>
   34 
   35 #include "fdt_pinctrl_if.h"
   36 
   37 #include <dev/fdt/fdt_common.h>
   38 #include <dev/fdt/fdt_pinctrl.h>
   39 
   40 int
   41 fdt_pinctrl_configure(device_t client, u_int index)
   42 {
   43         device_t pinctrl;
   44         phandle_t *configs;
   45         int i, nconfigs;
   46         char name[16];
   47 
   48         snprintf(name, sizeof(name), "pinctrl-%u", index);
   49         nconfigs = OF_getencprop_alloc_multi(ofw_bus_get_node(client), name,
   50             sizeof(*configs), (void **)&configs);
   51         if (nconfigs < 0)
   52                 return (ENOENT);
   53         if (nconfigs == 0)
   54                 return (0); /* Empty property is documented as valid. */
   55         for (i = 0; i < nconfigs; i++) {
   56                 if ((pinctrl = OF_device_from_xref(configs[i])) != NULL)
   57                         FDT_PINCTRL_CONFIGURE(pinctrl, configs[i]);
   58         }
   59         OF_prop_free(configs);
   60         return (0);
   61 }
   62 
   63 int
   64 fdt_pinctrl_configure_by_name(device_t client, const char * name)
   65 {
   66         char * names;
   67         int i, offset, nameslen;
   68 
   69         nameslen = OF_getprop_alloc(ofw_bus_get_node(client), "pinctrl-names",
   70             (void **)&names);
   71         if (nameslen <= 0)
   72                 return (ENOENT);
   73         for (i = 0, offset = 0; offset < nameslen; i++) {
   74                 if (strcmp(name, &names[offset]) == 0)
   75                         break;
   76                 offset += strlen(&names[offset]) + 1;
   77         }
   78         OF_prop_free(names);
   79         if (offset < nameslen)
   80                 return (fdt_pinctrl_configure(client, i));
   81         else
   82                 return (ENOENT);
   83 }
   84 
   85 static int
   86 pinctrl_register_children(device_t pinctrl, phandle_t parent,
   87     const char *pinprop)
   88 {
   89         phandle_t node;
   90 
   91         /*
   92          * Recursively descend from parent, looking for nodes that have the
   93          * given property, and associate the pinctrl device_t with each one.
   94          */
   95         for (node = OF_child(parent); node != 0; node = OF_peer(node)) {
   96                 pinctrl_register_children(pinctrl, node, pinprop);
   97                 if (pinprop == NULL || OF_hasprop(node, pinprop)) {
   98                         OF_device_register_xref(OF_xref_from_node(node),
   99                             pinctrl);
  100                 }
  101         }
  102         return (0);
  103 }
  104 
  105 int
  106 fdt_pinctrl_register(device_t pinctrl, const char *pinprop)
  107 {
  108         phandle_t node;
  109         int ret;
  110 
  111         TSENTER();
  112         node = ofw_bus_get_node(pinctrl);
  113         OF_device_register_xref(OF_xref_from_node(node), pinctrl);
  114         ret = pinctrl_register_children(pinctrl, node, pinprop);
  115         TSEXIT();
  116 
  117         return (ret);
  118 }
  119 
  120 static int
  121 pinctrl_configure_children(device_t pinctrl, phandle_t parent)
  122 {
  123         phandle_t node, *configs;
  124         int i, nconfigs;
  125 
  126         TSENTER();
  127 
  128         for (node = OF_child(parent); node != 0; node = OF_peer(node)) {
  129                 if (!ofw_bus_node_status_okay(node))
  130                         continue;
  131                 pinctrl_configure_children(pinctrl, node);
  132                 nconfigs = OF_getencprop_alloc_multi(node, "pinctrl-0",
  133                     sizeof(*configs), (void **)&configs);
  134                 if (nconfigs <= 0)
  135                         continue;
  136                 if (bootverbose) {
  137                         char name[32];
  138                         OF_getprop(node, "name", &name, sizeof(name));
  139                         printf("Processing %d pin-config node(s) in pinctrl-0 for %s\n",
  140                             nconfigs, name);
  141                 }
  142                 for (i = 0; i < nconfigs; i++) {
  143                         if (OF_device_from_xref(configs[i]) == pinctrl)
  144                                 FDT_PINCTRL_CONFIGURE(pinctrl, configs[i]);
  145                 }
  146                 OF_prop_free(configs);
  147         }
  148         TSEXIT();
  149         return (0);
  150 }
  151 
  152 int
  153 fdt_pinctrl_configure_tree(device_t pinctrl)
  154 {
  155 
  156         return (pinctrl_configure_children(pinctrl, OF_peer(0)));
  157 }
  158 

Cache object: de276043e2218923d94ef279a2746b29


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