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$");
   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/intr_machdep.h>
   52 #include <machine/clock.h>      /* for DELAY */
   53 #include <machine/resource.h>
   54 
   55 #include <mips/rmi/board.h>
   56 #include <mips/rmi/pic.h>
   57 #include <mips/rmi/interrupt.h>
   58 #include <mips/rmi/msgring.h>
   59 #include <mips/rmi/iomap.h>
   60 #include <mips/rmi/rmi_mips_exts.h>
   61 
   62 #include <mips/rmi/dev/xlr/atx_cpld.h>
   63 #include <mips/rmi/dev/xlr/xgmac_mdio.h>
   64 
   65 extern bus_space_tag_t uart_bus_space_mem;
   66 
   67 static struct resource *
   68 iodi_alloc_resource(device_t, device_t, int, int *,
   69     rman_res_t, rman_res_t, rman_res_t, u_int);
   70 
   71 static int
   72 iodi_activate_resource(device_t, device_t, int, int,
   73     struct resource *);
   74 static int
   75 iodi_setup_intr(device_t, device_t, struct resource *, int,
   76     driver_filter_t *, driver_intr_t *, void *, void **);
   77 
   78 struct iodi_softc *iodi_softc;  /* There can be only one. */
   79 
   80 /*
   81  * We will manage the Flash/PCMCIA devices in IODI for now.
   82  * The NOR flash, Compact flash etc. which can be connected on 
   83  * various chip selects on the peripheral IO, should have a 
   84  * separate bus later.
   85  */
   86 static void
   87 bridge_pcmcia_ack(int irq)
   88 {
   89         xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_FLASH_OFFSET);
   90 
   91         xlr_write_reg(mmio, 0x60, 0xffffffff);
   92 }
   93 
   94 static int
   95 iodi_setup_intr(device_t dev, device_t child,
   96     struct resource *ires, int flags, driver_filter_t *filt,
   97     driver_intr_t *intr, void *arg, void **cookiep)
   98 {
   99         const char *name = device_get_name(child);
  100 
  101         if (strcmp(name, "uart") == 0) {
  102                 /* FIXME uart 1? */
  103                 cpu_establish_hardintr("uart", filt, intr, arg,
  104                     PIC_UART_0_IRQ, flags, cookiep);
  105                 pic_setup_intr(PIC_IRT_UART_0_INDEX, PIC_UART_0_IRQ, 0x1, 1);
  106         } else if (strcmp(name, "nlge") == 0) {
  107                 int irq;
  108 
  109                 /* This is a hack to pass in the irq */
  110                 irq = (intptr_t)ires->__r_i;
  111                 cpu_establish_hardintr("nlge", filt, intr, arg, irq, flags,
  112                     cookiep);
  113                 pic_setup_intr(irq - PIC_IRQ_BASE, irq, 0x1, 1);
  114         } else if (strcmp(name, "ehci") == 0) {
  115                 cpu_establish_hardintr("ehci", filt, intr, arg, PIC_USB_IRQ, flags,
  116                     cookiep);
  117                 pic_setup_intr(PIC_USB_IRQ - PIC_IRQ_BASE, PIC_USB_IRQ, 0x1, 1);
  118         } else if (strcmp(name, "ata") == 0) {
  119                 xlr_establish_intr("ata", filt, intr, arg, PIC_PCMCIA_IRQ, flags,
  120                     cookiep, bridge_pcmcia_ack);
  121                 pic_setup_intr(PIC_PCMCIA_IRQ - PIC_IRQ_BASE, PIC_PCMCIA_IRQ, 0x1, 1);
  122         }
  123         return (0);
  124 }
  125 
  126 static struct resource *
  127 iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
  128     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
  129 {
  130         struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
  131         const char *name = device_get_name(child);
  132         int unit;
  133 
  134 #ifdef DEBUG
  135         switch (type) {
  136         case SYS_RES_IRQ:
  137                 device_printf(bus, "IRQ resource - for %s %jx-%jx\n",
  138                     device_get_nameunit(child), start, end);
  139                 break;
  140 
  141         case SYS_RES_IOPORT:
  142                 device_printf(bus, "IOPORT resource - for %s %jx-%jx\n",
  143                     device_get_nameunit(child), start, end);
  144                 break;
  145 
  146         case SYS_RES_MEMORY:
  147                 device_printf(bus, "MEMORY resource - for %s %jx-%jx\n",
  148                     device_get_nameunit(child), start, end);
  149                 break;
  150         }
  151 #endif
  152 
  153         if (strcmp(name, "uart") == 0) {
  154                 if ((unit = device_get_unit(child)) == 0) {     /* uart 0 */
  155                         res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
  156                 } else if (unit == 1) {
  157                         res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
  158                 } else
  159                         printf("%s: Unknown uart unit\n", __FUNCTION__);
  160 
  161                 res->r_bustag = uart_bus_space_mem;
  162         } else if (strcmp(name, "ehci") == 0) {
  163                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1ef24000);
  164                 res->r_bustag = rmi_pci_bus_space;
  165         } else if (strcmp(name, "cfi") == 0) {
  166                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1c000000);
  167                 res->r_bustag = 0;
  168         } else if (strcmp(name, "ata") == 0) {
  169                 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1d000000);
  170                 res->r_bustag = rmi_pci_bus_space;  /* byte swapping (not really PCI) */
  171         }
  172         /* res->r_start = *rid; */
  173         return (res);
  174 }
  175 
  176 static int
  177 iodi_activate_resource(device_t bus, device_t child, int type, int rid,
  178     struct resource *r)
  179 {
  180         return (0);
  181 }
  182 
  183 /* prototypes */
  184 static int iodi_probe(device_t);
  185 static int iodi_attach(device_t);
  186 static int iodi_detach(device_t);
  187 static void iodi_identify(driver_t *, device_t);
  188 
  189 int
  190 iodi_probe(device_t dev)
  191 {
  192         return (BUS_PROBE_NOWILDCARD);
  193 }
  194 
  195 void
  196 iodi_identify(driver_t * driver, device_t parent)
  197 {
  198 
  199         BUS_ADD_CHILD(parent, 0, "iodi", 0);
  200 }
  201 
  202 int
  203 iodi_attach(device_t dev)
  204 {
  205         device_t tmpd;
  206         int i;
  207 
  208         /*
  209          * Attach each devices
  210          */
  211         device_add_child(dev, "uart", 0);
  212         device_add_child(dev, "xlr_i2c", 0);
  213         device_add_child(dev, "xlr_i2c", 1);
  214         device_add_child(dev, "pcib", 0);
  215         device_add_child(dev, "rmisec", -1);
  216 
  217         if (xlr_board_info.usb)
  218                 device_add_child(dev, "ehci", 0);
  219 
  220         if (xlr_board_info.cfi)
  221                 device_add_child(dev, "cfi", 0);
  222 
  223         if (xlr_board_info.ata)
  224                 device_add_child(dev, "ata", 0);
  225 
  226         for (i = 0; i < 3; i++) {
  227                 if (xlr_board_info.gmac_block[i].enabled == 0)
  228                         continue;
  229                 tmpd = device_add_child(dev, "nlna", i);
  230                 device_set_ivars(tmpd, &xlr_board_info.gmac_block[i]);
  231         }
  232 
  233         bus_generic_probe(dev);
  234         bus_generic_attach(dev);
  235         return 0;
  236 }
  237 
  238 int
  239 iodi_detach(device_t dev)
  240 {
  241         device_t nlna_dev;
  242         int error, i, ret;
  243 
  244         error = 0;
  245         ret = 0;
  246         for (i = 0; i < 3; i++) {
  247                 nlna_dev = device_find_child(dev, "nlna", i);
  248                 if (nlna_dev != NULL)
  249                         error = bus_generic_detach(nlna_dev);
  250                 if (error)
  251                         ret = error;
  252         }
  253         return ret;
  254 }
  255 
  256 static device_method_t iodi_methods[] = {
  257         DEVMETHOD(device_probe, iodi_probe),
  258         DEVMETHOD(device_attach, iodi_attach),
  259         DEVMETHOD(device_detach, iodi_detach),
  260         DEVMETHOD(device_identify, iodi_identify),
  261         DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
  262         DEVMETHOD(bus_activate_resource, iodi_activate_resource),
  263         DEVMETHOD(bus_add_child, bus_generic_add_child),
  264         DEVMETHOD(bus_setup_intr, iodi_setup_intr),
  265         {0, 0},
  266 };
  267 
  268 static driver_t iodi_driver = {
  269         "iodi",
  270         iodi_methods,
  271         1                       /* no softc */
  272 };
  273 static devclass_t iodi_devclass;
  274 
  275 DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);

Cache object: 90e26454fb31436dd997338de94fc2ec


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