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/iicbus/pmic/rockchip/rk817.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
    3  *
    4  * Copyright (c) 2021, 2022 Soren Schmidt <sos@deepcore.dk>
    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 AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/bus.h>
   34 #include <sys/clock.h>
   35 #include <sys/kernel.h>
   36 #include <sys/module.h>
   37 #include <sys/mutex.h>
   38 #include <sys/rman.h>
   39 #include <machine/bus.h>
   40 
   41 #include <dev/iicbus/iiconf.h>
   42 #include <dev/iicbus/iicbus.h>
   43 
   44 #include <dev/ofw/ofw_bus.h>
   45 #include <dev/ofw/ofw_bus_subr.h>
   46 
   47 #include <dev/iicbus/pmic/rockchip/rk817reg.h>
   48 #include <dev/iicbus/pmic/rockchip/rk8xx.h>
   49 
   50 
   51 static struct ofw_compat_data compat_data[] = {
   52         {"rockchip,rk809",      RK809},
   53         {"rockchip,rk817",      RK817},
   54         {NULL,                  0}
   55 };
   56 
   57 static struct rk8xx_regdef rk809_regdefs[] = {
   58         {
   59                 .id = RK809_DCDC1,
   60                 .name = "DCDC_REG1",
   61                 .enable_reg = RK817_DCDC_EN,
   62                 .enable_mask = 0x11,
   63                 .voltage_reg = RK817_DCDC1_ON_VSEL,
   64                 .voltage_mask = 0x7f,
   65                 .voltage_min = 500000,
   66                 .voltage_max = 1487500,
   67                 .voltage_min2 = 1500000,
   68                 .voltage_max2 = 2400000,
   69                 .voltage_step = 12500,
   70                 .voltage_step2 = 100000,
   71                 .voltage_nstep = 177,
   72         },
   73         {
   74                 .id = RK809_DCDC2,
   75                 .name = "DCDC_REG2",
   76                 .enable_reg = RK817_DCDC_EN,
   77                 .enable_mask = 0x22,
   78                 .voltage_reg = RK817_DCDC2_ON_VSEL,
   79                 .voltage_mask = 0x7f,
   80                 .voltage_min = 500000,
   81                 .voltage_max = 1487500,
   82                 .voltage_min2 = 1500000,
   83                 .voltage_max2 = 2400000,
   84                 .voltage_step = 12500,
   85                 .voltage_step2 = 100000,
   86                 .voltage_nstep = 177,
   87         },
   88         {
   89                 .id = RK809_DCDC3,
   90                 .name = "DCDC_REG3",
   91                 .enable_reg = RK817_DCDC_EN,
   92                 .enable_mask = 0x44,
   93                 .voltage_reg = RK817_DCDC3_ON_VSEL,
   94                 .voltage_mask = 0x7f,
   95                 .voltage_min = 500000,
   96                 .voltage_max = 1487500,
   97                 .voltage_min2 = 1500000,
   98                 .voltage_max2 = 2400000,
   99                 .voltage_step = 12500,
  100                 .voltage_step2 = 100000,
  101                 .voltage_nstep = 177,
  102         },
  103         {
  104                 .id = RK809_DCDC4,
  105                 .name = "DCDC_REG4",
  106                 .enable_reg = RK817_DCDC_EN,
  107                 .enable_mask = 0x88,
  108                 .voltage_reg = RK817_DCDC4_ON_VSEL,
  109                 .voltage_mask = 0x7f,
  110                 .voltage_min = 500000,
  111                 .voltage_max = 1487500,
  112                 .voltage_min2 = 1500000,
  113                 .voltage_max2 = 3400000,
  114                 .voltage_step = 12500,
  115                 .voltage_step2 = 100000,
  116                 .voltage_nstep = 195,
  117         },
  118         {
  119                 .id = RK809_DCDC5,
  120                 .name = "DCDC_REG5",
  121                 .enable_reg = RK817_LDO_EN3,
  122                 .enable_mask = 0x22,
  123                 .voltage_reg = RK817_BOOST_ON_VSEL,
  124                 .voltage_mask = 0x07,
  125                 .voltage_min = 1600000, /* cheat is 1.5V */
  126                 .voltage_max = 3400000,
  127                 .voltage_min2 = 3500000,
  128                 .voltage_max2 = 3600000,
  129                 .voltage_step = 200000,
  130                 .voltage_step2 = 300000,
  131                 .voltage_nstep = 8,
  132         },
  133         {
  134                 .id = RK809_LDO1,
  135                 .name = "LDO_REG1",
  136                 .enable_reg = RK817_LDO_EN1,
  137                 .enable_mask = 0x11,
  138                 .voltage_reg = RK817_LDO1_ON_VSEL,
  139                 .voltage_mask = 0x7f,
  140                 .voltage_min = 600000,
  141                 .voltage_max = 3400000,
  142                 .voltage_step = 25000,
  143                 .voltage_nstep = 112,
  144         },
  145         {
  146                 .id = RK809_LDO2,
  147                 .name = "LDO_REG2",
  148                 .enable_reg = RK817_LDO_EN1,
  149                 .enable_mask = 0x22,
  150                 .voltage_reg = RK817_LDO2_ON_VSEL,
  151                 .voltage_mask = 0x7f,
  152                 .voltage_min = 600000,
  153                 .voltage_max = 3400000,
  154                 .voltage_step = 25000,
  155                 .voltage_nstep = 112,
  156         },
  157         {
  158                 .id = RK809_LDO3,
  159                 .name = "LDO_REG3",
  160                 .enable_reg = RK817_LDO_EN1,
  161                 .enable_mask = 0x44,
  162                 .voltage_reg = RK817_LDO3_ON_VSEL,
  163                 .voltage_mask = 0x7f,
  164                 .voltage_min = 600000,
  165                 .voltage_max = 3400000,
  166                 .voltage_step = 25000,
  167                 .voltage_nstep = 112,
  168         },
  169         {
  170                 .id = RK809_LDO4,
  171                 .name = "LDO_REG4",
  172                 .enable_reg = RK817_LDO_EN1,
  173                 .enable_mask = 0x88,
  174                 .voltage_reg = RK817_LDO4_ON_VSEL,
  175                 .voltage_mask = 0x7f,
  176                 .voltage_min = 600000,
  177                 .voltage_max = 3400000,
  178                 .voltage_step = 25000,
  179                 .voltage_nstep = 112,
  180         },
  181         {
  182                 .id = RK809_LDO5,
  183                 .name = "LDO_REG5",
  184                 .enable_reg = RK817_LDO_EN2,
  185                 .enable_mask = 0x11,
  186                 .voltage_reg = RK817_LDO5_ON_VSEL,
  187                 .voltage_mask = 0x7f,
  188                 .voltage_min = 600000,
  189                 .voltage_max = 3400000,
  190                 .voltage_step = 25000,
  191                 .voltage_nstep = 112,
  192         },
  193         {
  194                 .id = RK809_LDO6,
  195                 .name = "LDO_REG6",
  196                 .enable_reg = RK817_LDO_EN2,
  197                 .enable_mask = 0x22,
  198                 .voltage_reg = RK817_LDO6_ON_VSEL,
  199                 .voltage_mask = 0x7f,
  200                 .voltage_min = 600000,
  201                 .voltage_max = 3400000,
  202                 .voltage_step = 25000,
  203                 .voltage_nstep = 112,
  204         },
  205         {
  206                 .id = RK809_LDO7,
  207                 .name = "LDO_REG7",
  208                 .enable_reg = RK817_LDO_EN2,
  209                 .enable_mask = 0x44,
  210                 .voltage_reg = RK817_LDO7_ON_VSEL,
  211                 .voltage_mask = 0x7f,
  212                 .voltage_min = 600000,
  213                 .voltage_max = 3400000,
  214                 .voltage_step = 25000,
  215                 .voltage_nstep = 112,
  216         },
  217         {
  218                 .id = RK809_LDO8,
  219                 .name = "LDO_REG8",
  220                 .enable_reg = RK817_LDO_EN2,
  221                 .enable_mask = 0x88,
  222                 .voltage_reg = RK817_LDO8_ON_VSEL,
  223                 .voltage_mask = 0x7f,
  224                 .voltage_min = 600000,
  225                 .voltage_max = 3400000,
  226                 .voltage_step = 25000,
  227                 .voltage_nstep = 112,
  228         },
  229         {
  230                 .id = RK809_LDO9,
  231                 .name = "LDO_REG9",
  232                 .enable_reg = RK817_LDO_EN3,
  233                 .enable_mask = 0x11,
  234                 .voltage_reg = RK817_LDO9_ON_VSEL,
  235                 .voltage_mask = 0x7f,
  236                 .voltage_min = 600000,
  237                 .voltage_max = 3400000,
  238                 .voltage_step = 25000,
  239                 .voltage_nstep = 112,
  240         },
  241         {
  242                 .id = RK809_SWITCH1,
  243                 .name = "SWITCH_REG1",
  244                 .enable_reg = RK817_LDO_EN3,
  245                 .enable_mask = 0x44,
  246                 .voltage_min = 3300000,
  247                 .voltage_max = 3300000,
  248                 .voltage_nstep = 0,
  249         },
  250         {
  251                 .id = RK809_SWITCH2,
  252                 .name = "SWITCH_REG2",
  253                 .enable_reg = RK817_LDO_EN3,
  254                 .enable_mask = 0x88,
  255                 .voltage_min = 3300000,
  256                 .voltage_max = 3300000,
  257                 .voltage_nstep = 0,
  258         },
  259 };
  260 
  261 static struct rk8xx_regdef rk817_regdefs[] = {
  262         {
  263                 .id = RK817_DCDC1,
  264                 .name = "DCDC_REG1",
  265                 .enable_reg = RK817_DCDC_EN,
  266                 .enable_mask = 0x11,
  267                 .voltage_reg = RK817_DCDC1_ON_VSEL,
  268                 .voltage_mask = 0x7f,
  269                 .voltage_min = 500000,
  270                 .voltage_max = 1487500,
  271                 .voltage_min2 = 1500000,
  272                 .voltage_max2 = 2400000,
  273                 .voltage_step = 12500,
  274                 .voltage_step2 = 100000,
  275                 .voltage_nstep = 177,
  276         },
  277         {
  278                 .id = RK817_DCDC2,
  279                 .name = "DCDC_REG2",
  280                 .enable_reg = RK817_DCDC_EN,
  281                 .enable_mask = 0x22,
  282                 .voltage_reg = RK817_DCDC2_ON_VSEL,
  283                 .voltage_mask = 0x7f,
  284                 .voltage_min = 500000,
  285                 .voltage_max = 1487500,
  286                 .voltage_min2 = 1500000,
  287                 .voltage_max2 = 2400000,
  288                 .voltage_step = 12500,
  289                 .voltage_step2 = 100000,
  290                 .voltage_nstep = 177,
  291         },
  292         {
  293                 .id = RK817_DCDC3,
  294                 .name = "DCDC_REG3",
  295                 .enable_reg = RK817_DCDC_EN,
  296                 .enable_mask = 0x44,
  297                 .voltage_reg = RK817_DCDC3_ON_VSEL,
  298                 .voltage_mask = 0x7f,
  299                 .voltage_min = 500000,
  300                 .voltage_max = 1487500,
  301                 .voltage_min2 = 1500000,
  302                 .voltage_max2 = 2400000,
  303                 .voltage_step = 12500,
  304                 .voltage_step2 = 100000,
  305                 .voltage_nstep = 177,
  306         },
  307         {
  308                 .id = RK817_DCDC4,
  309                 .name = "DCDC_REG4",
  310                 .enable_reg = RK817_DCDC_EN,
  311                 .enable_mask = 0x88,
  312                 .voltage_reg = RK817_DCDC4_ON_VSEL,
  313                 .voltage_mask = 0x7f,
  314                 .voltage_min = 500000,
  315                 .voltage_max = 1487500,
  316                 .voltage_min2 = 1500000,
  317                 .voltage_max2 = 3400000,
  318                 .voltage_step = 12500,
  319                 .voltage_step2 = 100000,
  320                 .voltage_nstep = 195,
  321         },
  322         {
  323                 .id = RK817_LDO1,
  324                 .name = "LDO_REG1",
  325                 .enable_reg = RK817_LDO_EN1,
  326                 .enable_mask = 0x11,
  327                 .voltage_reg = RK817_LDO1_ON_VSEL,
  328                 .voltage_mask = 0x7f,
  329                 .voltage_min = 600000,
  330                 .voltage_max = 3400000,
  331                 .voltage_step = 25000,
  332                 .voltage_nstep = 112,
  333         },
  334         {
  335                 .id = RK817_LDO2,
  336                 .name = "LDO_REG2",
  337                 .enable_reg = RK817_LDO_EN1,
  338                 .enable_mask = 0x22,
  339                 .voltage_reg = RK817_LDO2_ON_VSEL,
  340                 .voltage_mask = 0x7f,
  341                 .voltage_min = 600000,
  342                 .voltage_max = 3400000,
  343                 .voltage_step = 25000,
  344                 .voltage_nstep = 112,
  345         },
  346         {
  347                 .id = RK817_LDO3,
  348                 .name = "LDO_REG3",
  349                 .enable_reg = RK817_LDO_EN1,
  350                 .enable_mask = 0x44,
  351                 .voltage_reg = RK817_LDO3_ON_VSEL,
  352                 .voltage_mask = 0x7f,
  353                 .voltage_min = 600000,
  354                 .voltage_max = 3400000,
  355                 .voltage_step = 25000,
  356                 .voltage_nstep = 112,
  357         },
  358         {
  359                 .id = RK817_LDO4,
  360                 .name = "LDO_REG4",
  361                 .enable_reg = RK817_LDO_EN1,
  362                 .enable_mask = 0x88,
  363                 .voltage_reg = RK817_LDO4_ON_VSEL,
  364                 .voltage_mask = 0x7f,
  365                 .voltage_min = 600000,
  366                 .voltage_max = 3400000,
  367                 .voltage_step = 25000,
  368                 .voltage_nstep = 112,
  369         },
  370         {
  371                 .id = RK817_LDO5,
  372                 .name = "LDO_REG5",
  373                 .enable_reg = RK817_LDO_EN2,
  374                 .enable_mask = 0x11,
  375                 .voltage_reg = RK817_LDO5_ON_VSEL,
  376                 .voltage_mask = 0x7f,
  377                 .voltage_min = 600000,
  378                 .voltage_max = 3400000,
  379                 .voltage_step = 25000,
  380                 .voltage_nstep = 112,
  381         },
  382         {
  383                 .id = RK817_LDO6,
  384                 .name = "LDO_REG6",
  385                 .enable_reg = RK817_LDO_EN2,
  386                 .enable_mask = 0x22,
  387                 .voltage_reg = RK817_LDO6_ON_VSEL,
  388                 .voltage_mask = 0x7f,
  389                 .voltage_min = 600000,
  390                 .voltage_max = 3400000,
  391                 .voltage_step = 25000,
  392                 .voltage_nstep = 112,
  393         },
  394         {
  395                 .id = RK817_LDO7,
  396                 .name = "LDO_REG7",
  397                 .enable_reg = RK817_LDO_EN2,
  398                 .enable_mask = 0x44,
  399                 .voltage_reg = RK817_LDO7_ON_VSEL,
  400                 .voltage_mask = 0x7f,
  401                 .voltage_min = 600000,
  402                 .voltage_max = 3400000,
  403                 .voltage_step = 25000,
  404                 .voltage_nstep = 112,
  405         },
  406         {
  407                 .id = RK817_LDO8,
  408                 .name = "LDO_REG8",
  409                 .enable_reg = RK817_LDO_EN2,
  410                 .enable_mask = 0x88,
  411                 .voltage_reg = RK817_LDO8_ON_VSEL,
  412                 .voltage_mask = 0x7f,
  413                 .voltage_min = 600000,
  414                 .voltage_max = 3400000,
  415                 .voltage_step = 25000,
  416                 .voltage_nstep = 112,
  417         },
  418         {
  419                 .id = RK817_LDO9,
  420                 .name = "LDO_REG9",
  421                 .enable_reg = RK817_LDO_EN3,
  422                 .enable_mask = 0x11,
  423                 .voltage_reg = RK817_LDO9_ON_VSEL,
  424                 .voltage_mask = 0x7f,
  425                 .voltage_min = 600000,
  426                 .voltage_max = 3400000,
  427                 .voltage_step = 25000,
  428                 .voltage_nstep = 112,
  429         },
  430         {
  431                 .id = RK817_BOOST,
  432                 .name = "BOOST",
  433                 .enable_reg = RK817_LDO_EN3,
  434                 .enable_mask = 0x22,
  435                 .voltage_reg = RK817_BOOST_ON_VSEL,
  436                 .voltage_mask = 0x07,
  437                 .voltage_min = 4700000,
  438                 .voltage_max = 5400000,
  439                 .voltage_step = 100000,
  440                 .voltage_nstep = 8,
  441         },
  442         {
  443                 .id = RK817_OTG_SWITCH,
  444                 .name = "OTG_SWITCH",
  445                 .enable_reg = RK817_LDO_EN3,
  446                 .enable_mask = 0x44,
  447                 .voltage_nstep = 0,
  448         },
  449 };
  450 
  451 static int
  452 rk817_probe(device_t dev)
  453 {
  454         if (!ofw_bus_status_okay(dev))
  455                 return (ENXIO);
  456 
  457         switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
  458         case RK809:
  459                 device_set_desc(dev, "RockChip RK809 PMIC");
  460                 break;
  461         case RK817:
  462                 device_set_desc(dev, "RockChip RK817 PMIC");
  463                 break;
  464         default:
  465                 return (ENXIO);
  466         }
  467 
  468         return (BUS_PROBE_DEFAULT);
  469 }
  470 
  471 static int
  472 rk817_attach(device_t dev)
  473 {
  474         struct rk8xx_softc *sc;
  475 
  476         sc = device_get_softc(dev);
  477         sc->dev = dev;
  478 
  479         sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
  480         switch (sc->type) {
  481         case RK809:
  482                 sc->regdefs = rk809_regdefs;
  483                 sc->nregs = nitems(rk809_regdefs);
  484                 break;
  485         case RK817:
  486                 sc->regdefs = rk817_regdefs;
  487                 sc->nregs = nitems(rk817_regdefs);
  488                 break;
  489         default:
  490                 device_printf(dev, "Unknown type %d\n", sc->type);
  491                 return (ENXIO);
  492         }
  493         sc->rtc_regs.secs = RK817_RTC_SECONDS;
  494         sc->rtc_regs.secs_mask = RK817_RTC_SECONDS_MASK;
  495         sc->rtc_regs.minutes = RK817_RTC_MINUTES;
  496         sc->rtc_regs.minutes_mask = RK817_RTC_MINUTES_MASK;
  497         sc->rtc_regs.hours = RK817_RTC_HOURS;
  498         sc->rtc_regs.hours_mask = RK817_RTC_HOURS_MASK;
  499         sc->rtc_regs.days = RK817_RTC_DAYS;
  500         sc->rtc_regs.days_mask = RK817_RTC_DAYS_MASK;
  501         sc->rtc_regs.months = RK817_RTC_MONTHS;
  502         sc->rtc_regs.months_mask = RK817_RTC_MONTHS_MASK;
  503         sc->rtc_regs.years = RK817_RTC_YEARS;
  504         sc->rtc_regs.weeks = RK817_RTC_WEEKS_MASK;
  505         sc->rtc_regs.ctrl = RK817_RTC_CTRL;
  506         sc->rtc_regs.ctrl_stop_mask = RK817_RTC_CTRL_STOP;
  507         sc->rtc_regs.ctrl_ampm_mask = RK817_RTC_AMPM_MODE;
  508         sc->rtc_regs.ctrl_gettime_mask = RK817_RTC_GET_TIME;
  509         sc->rtc_regs.ctrl_readsel_mask = RK817_RTC_READSEL;
  510         sc->dev_ctrl.dev_ctrl_reg = RK817_SYS_CFG3;
  511         sc->dev_ctrl.pwr_off_mask = RK817_SYS_CFG3_OFF;
  512         sc->dev_ctrl.pwr_rst_mask = RK817_SYS_CFG3_RST;
  513 
  514         return (rk8xx_attach(sc));
  515 }
  516 
  517 static device_method_t rk817_methods[] = {
  518         DEVMETHOD(device_probe,         rk817_probe),
  519         DEVMETHOD(device_attach,        rk817_attach),
  520 
  521         DEVMETHOD_END
  522 };
  523 
  524 DEFINE_CLASS_1(rk817_pmu, rk817_driver, rk817_methods,
  525     sizeof(struct rk8xx_softc), rk8xx_driver);
  526 
  527 EARLY_DRIVER_MODULE(rk817_pmu, iicbus, rk817_driver, 0, 0,
  528     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
  529 EARLY_DRIVER_MODULE(iicbus, rk817_pmu, iicbus_driver, 0, 0,
  530     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
  531 MODULE_DEPEND(rk817_pmu, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
  532 MODULE_VERSION(rk817_pmu, 1);

Cache object: 9fbcd2738dba177f0e64a6b289717035


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