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/mips/rmi/iodi.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) 2003-2009 RMI Corporation
    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  * 3. Neither the name of RMI Corporation, nor the names of its contributors,
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * RMI_BSD
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/9.0/sys/mips/rmi/iodi.c 223562 2011-06-26 10:07:48Z kevlo $");
   34 
   35 #define __RMAN_RESOURCE_VISIBLE
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/bus.h>
   39 #include <sys/kernel.h>
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <sys/reboot.h>
   43 #include <sys/rman.h>
   44 #include <sys/types.h>
   45 #include <sys/malloc.h>
   46 #include <sys/interrupt.h>
   47 #include <sys/module.h>
   48 
   49 #include <machine/cpu.h>
   50 #include <machine/bus.h>
   51 #include <machine/param.h>
   52 #include <machine/intr_machdep.h>
   53 #include <machine/clock.h>      /* for DELAY */
   54 #include <machine/resource.h>
   55 
   56 #include <mips/rmi/board.h>
   57 #include <mips/rmi/pic.h>
   58 #include <mips/rmi/interrupt.h>
   59 #include <mips/rmi/msgring.h>
   60 #include <mips/rmi/iomap.h>
   61 #include <mips/rmi/rmi_mips_exts.h>
   62 
   63 #include <mips/rmi/dev/xlr/atx_cpld.h>
   64 #include <mips/rmi/dev/xlr/xgmac_mdio.h>
   65 
   66 extern bus_space_tag_t uart_bus_space_mem;
   67 
   68 static struct resource *
   69 iodi_alloc_resource(device_t, device_t, int, int *,
   70     u_long, u_long, u_long, u_int);
   71 
   72 static int
   73 iodi_activate_resource(device_t, device_t, int, int,
   74     struct resource *);
   75 static int
   76 iodi_setup_intr(device_t, device_t, struct resource *, int,
   77     driver_filter_t *, driver_intr_t *, void *, void **);
   78 
   79 struct iodi_softc *iodi_softc;  /* There can be only one. */
   80 
   81 /*
   82  * We will manage the Flash/PCMCIA devices in IODI for now.
   83  * The NOR flash, Compact flash etc. which can be connected on 
   84  * various chip selects on the peripheral IO, should have a 
   85  * separate bus later.
   86  */
   87 static void
   88 bridge_pcmcia_ack(int irq)
   89 {
   90         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_FLASH_OFFSET);
   91 
   92         xlr_write_reg(mmio, 0x60, 0xffffffff);
   93 }
   94 
   95 static int
   96 iodi_setup_intr(device_t dev, device_t child,
   97     struct resource *ires, int flags, driver_filter_t *filt,
   98     driver_intr_t *intr, void *arg, void **cookiep)
   99 {
  100         const char *name = device_get_name(child);
  101 
  102         if (strcmp(name, "uart") == 0) {
  103                 /* FIXME uart 1? */
  104                 cpu_establish_hardintr("uart", filt, intr, arg,
  105                     PIC_UART_0_IRQ, flags, cookiep);
  106                 pic_setup_intr(PIC_IRT_UART_0_INDEX, PIC_UART_0_IRQ, 0x1, 1);
  107         } else if (strcmp(name, "rge") == 0 || strcmp(name, "nlge") == 0) {
  108                 int irq;
  109 
  110                 /* This is a hack to pass in the irq */
  111                 irq = (intptr_t)ires->__r_i;
  112                 cpu_establish_hardintr("rge", filt, intr, arg, irq, flags,
  113                     cookiep);
  114                 pic_setup_intr(irq - PIC_IRQ_BASE, irq, 0x1, 1);
  115         } else if (strcmp(name, "ehci") == 0) {
  116                 cpu_establish_hardintr("ehci", filt, intr, arg, PIC_USB_IRQ, flags,
  117                     cookiep);
  118                 pic_setup_intr(PIC_USB_IRQ - PIC_IRQ_BASE, PIC_USB_IRQ, 0x1, 1);
  119         } else if (strcmp(name, "ata") == 0) {
  120                 xlr_establish_intr("ata", filt, intr, arg, PIC_PCMCIA_IRQ, flags,
  121                     cookiep, bridge_pcmcia_ack);
  122                 pic_setup_intr(PIC_PCMCIA_IRQ - PIC_IRQ_BASE, PIC_PCMCIA_IRQ, 0x1, 1);
  123         }
  124         return (0);
  125 }
  126 
  127 static struct resource *
  128 iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
  129     u_long start, u_long end, u_long count, u_int flags)
  130 {
  131         struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
  132         const char *name = device_get_name(child);
  133         int unit;
  134 
  135 #ifdef DEBUG
  136         switch (type) {
  137         case SYS_RES_IRQ:
  138                 device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
  139                     device_get_nameunit(child), start, end);
  140                 break;
  141 
  142         case SYS_RES_IOPORT:
  143                 device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
  144                     device_get_nameunit(child), start, end);
  145                 break;
  146 
  147         case SYS_RES_MEMORY:
  148                 device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
  149                     device_get_nameunit(child), start, end);
  150                 break;
  151         }
  152 #endif
  153 
  154         if (strcmp(name, "uart") == 0) {
  155                 if ((unit = device_get_unit(child)) == 0) {     /* uart 0 */
  156                         res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
  157                 } else if (unit == 1) {
  158                         res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
  159                 } else
  160                         printf("%s: Unknown uart unit\n", __FUNCTION__);
  161 
  162                 res->r_bustag = uart_bus_space_mem;
  163         } else if (strcmp(name, "ehci") == 0) {
  164                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1ef24000);
  165                 res->r_bustag = rmi_pci_bus_space;
  166         } else if (strcmp(name, "cfi") == 0) {
  167                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1c000000);
  168                 res->r_bustag = 0;
  169         } else if (strcmp(name, "ata") == 0) {
  170                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1d000000);
  171                 res->r_bustag = rmi_pci_bus_space;  /* byte swapping (not really PCI) */
  172         }
  173         /* res->r_start = *rid; */
  174         return (res);
  175 }
  176 
  177 static int
  178 iodi_activate_resource(device_t bus, device_t child, int type, int rid,
  179     struct resource *r)
  180 {
  181         return (0);
  182 }
  183 
  184 /* prototypes */
  185 static int iodi_probe(device_t);
  186 static int iodi_attach(device_t);
  187 static int iodi_detach(device_t);
  188 static void iodi_identify(driver_t *, device_t);
  189 
  190 int
  191 iodi_probe(device_t dev)
  192 {
  193         return 0;
  194 }
  195 
  196 void
  197 iodi_identify(driver_t * driver, device_t parent)
  198 {
  199 
  200         BUS_ADD_CHILD(parent, 0, "iodi", 0);
  201 }
  202 
  203 int
  204 iodi_attach(device_t dev)
  205 {
  206         device_t tmpd;
  207         int i;
  208 
  209         /*
  210          * Attach each devices
  211          */
  212         device_add_child(dev, "uart", 0);
  213         device_add_child(dev, "xlr_i2c", 0);
  214         device_add_child(dev, "xlr_i2c", 1);
  215         device_add_child(dev, "pcib", 0);
  216         device_add_child(dev, "rmisec", -1);
  217 
  218         if (xlr_board_info.usb)
  219                 device_add_child(dev, "ehci", 0);
  220 
  221         if (xlr_board_info.cfi)
  222                 device_add_child(dev, "cfi", 0);
  223 
  224         if (xlr_board_info.ata)
  225                 device_add_child(dev, "ata", 0);
  226 
  227         if (xlr_board_info.gmac_block[0].enabled) {
  228                 tmpd = device_add_child(dev, "rge", 0);
  229                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
  230 
  231                 tmpd = device_add_child(dev, "rge", 1);
  232                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
  233 
  234                 tmpd = device_add_child(dev, "rge", 2);
  235                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
  236 
  237                 tmpd = device_add_child(dev, "rge", 3);
  238                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]);
  239         }
  240         if (xlr_board_info.gmac_block[1].enabled) {
  241                 if (xlr_board_info.gmac_block[1].type == XLR_GMAC) {
  242                         tmpd = device_add_child(dev, "rge", 4);
  243                         device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  244 
  245                         tmpd = device_add_child(dev, "rge", 5);
  246                         device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  247 
  248                         if (xlr_board_info.gmac_block[1].enabled & 0x4) {
  249                                 tmpd = device_add_child(dev, "rge", 6);
  250                                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  251                         }
  252 
  253                         if (xlr_board_info.gmac_block[1].enabled & 0x8) {
  254                                 tmpd = device_add_child(dev, "rge", 7);
  255                                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  256                         }
  257                 } else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) {
  258 #if 0                           /* XGMAC not yet */
  259                         tmpd = device_add_child(dev, "rge", 4);
  260                         device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  261 
  262                         tmpd = device_add_child(dev, "rge", 5);
  263                         device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]);
  264 #endif
  265                 } else 
  266                         device_printf(dev, "Unknown type of gmac 1\n"); 
  267         }
  268 
  269         /* This is to add the new GMAC driver. The above adds the old driver,
  270            which has been retained for now as the new driver is stabilized.
  271            The new driver is enabled with "option nlge". Make sure that only
  272            one of rge or nlge is enabled in the conf file. */
  273         for (i = 0; i < 3; i++) {
  274                 if (xlr_board_info.gmac_block[i].enabled == 0)
  275                         continue;
  276                 tmpd = device_add_child(dev, "nlna", i);
  277                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[i]);
  278         }
  279         bus_generic_probe(dev);
  280         bus_generic_attach(dev);
  281         return 0;
  282 }
  283 
  284 int
  285 iodi_detach(device_t dev)
  286 {
  287         device_t nlna_dev;
  288         int error, i, ret;
  289 
  290         error = 0;
  291         ret = 0;
  292         for (i = 0; i < 3; i++) {
  293                 nlna_dev = device_find_child(dev, "nlna", i);
  294                 if (nlna_dev != NULL)
  295                         error = bus_generic_detach(nlna_dev);
  296                 if (error)
  297                         ret = error;
  298         }
  299         return ret;
  300 }
  301 
  302 static device_method_t iodi_methods[] = {
  303         DEVMETHOD(device_probe, iodi_probe),
  304         DEVMETHOD(device_attach, iodi_attach),
  305         DEVMETHOD(device_detach, iodi_detach),
  306         DEVMETHOD(device_identify, iodi_identify),
  307         DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
  308         DEVMETHOD(bus_activate_resource, iodi_activate_resource),
  309         DEVMETHOD(bus_add_child, bus_generic_add_child),
  310         DEVMETHOD(bus_setup_intr, iodi_setup_intr),
  311         {0, 0},
  312 };
  313 
  314 static driver_t iodi_driver = {
  315         "iodi",
  316         iodi_methods,
  317         1                       /* no softc */
  318 };
  319 static devclass_t iodi_devclass;
  320 
  321 DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);

Cache object: 8f8ca20007d130c965b126da4a2a5eed


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