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/pcf/envctrl.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) 2004 Joerg Wunsch
    3  *
    4  * derived from sys/i386/isa/pcf.c which is:
    5  *
    6  * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/9.0/sys/dev/pcf/envctrl.c 181332 2008-08-05 17:39:37Z jhb $");
   32 
   33 /*
   34  * Device specific driver for the SUNW,envctrl device found on some
   35  * UltraSPARC Sun systems.  This device is a Philips PCF8584 sitting
   36  * on the Ebus2.
   37  */
   38 
   39 #include <sys/param.h>
   40 #include <sys/bus.h>
   41 #include <sys/conf.h>
   42 #include <sys/kernel.h>
   43 #include <sys/lock.h>
   44 #include <sys/malloc.h>
   45 #include <sys/module.h>
   46 #include <sys/mutex.h>
   47 #include <sys/resource.h>
   48 #include <sys/systm.h>
   49 #include <sys/uio.h>
   50 
   51 #include <dev/ofw/ofw_bus.h>
   52 
   53 #include <machine/bus.h>
   54 #include <machine/resource.h>
   55 
   56 #include <sys/rman.h>
   57 
   58 #include <dev/iicbus/iicbus.h>
   59 #include <dev/iicbus/iiconf.h>
   60 #include <dev/pcf/pcfvar.h>
   61 #include "iicbus_if.h"
   62 
   63 #undef PCF_DEFAULT_ADDR
   64 #define PCF_DEFAULT_ADDR        0x55 /* SUNW,pcf default */
   65 
   66 static int envctrl_probe(device_t);
   67 static int envctrl_attach(device_t);
   68 static int envctrl_detach(device_t);
   69 
   70 static device_method_t envctrl_methods[] = {
   71         /* device interface */
   72         DEVMETHOD(device_probe,         envctrl_probe),
   73         DEVMETHOD(device_attach,        envctrl_attach),
   74         DEVMETHOD(device_detach,        envctrl_detach),
   75 
   76         /* iicbus interface */
   77         DEVMETHOD(iicbus_callback,      iicbus_null_callback),
   78         DEVMETHOD(iicbus_repeated_start, pcf_repeated_start),
   79         DEVMETHOD(iicbus_start,         pcf_start),
   80         DEVMETHOD(iicbus_stop,          pcf_stop),
   81         DEVMETHOD(iicbus_write,         pcf_write),
   82         DEVMETHOD(iicbus_read,          pcf_read),
   83         DEVMETHOD(iicbus_reset,         pcf_rst_card),
   84         { 0, 0 }
   85 };
   86 
   87 static devclass_t envctrl_devclass;
   88 
   89 static driver_t envctrl_driver = {
   90         "envctrl",
   91         envctrl_methods,
   92         sizeof(struct pcf_softc),
   93 };
   94 
   95 static int
   96 envctrl_probe(device_t dev)
   97 {
   98 
   99         if (strcmp("SUNW,envctrl", ofw_bus_get_name(dev)) == 0) {
  100                 device_set_desc(dev, "EBus SUNW,envctrl");
  101                 return (0);
  102         }
  103         return (ENXIO);
  104 }
  105 
  106 static int
  107 envctrl_attach(device_t dev)
  108 {
  109         struct pcf_softc *sc;
  110         int rv = ENXIO;
  111 
  112         sc = DEVTOSOFTC(dev);
  113         mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);
  114 
  115         /* IO port is mandatory */
  116         sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  117                                                 &sc->rid_ioport, RF_ACTIVE);
  118         if (sc->res_ioport == 0) {
  119                 device_printf(dev, "cannot reserve I/O port range\n");
  120                 goto error;
  121         }
  122 
  123         sc->pcf_flags = device_get_flags(dev);
  124 
  125         if (!(sc->pcf_flags & IIC_POLLED)) {
  126                 sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rid_irq,
  127                                                      RF_ACTIVE);
  128                 if (sc->res_irq == 0) {
  129                         device_printf(dev, "can't reserve irq, polled mode.\n");
  130                         sc->pcf_flags |= IIC_POLLED;
  131                 }
  132         }
  133 
  134         /* reset the chip */
  135         pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
  136 
  137         rv = bus_setup_intr(dev, sc->res_irq,
  138                             INTR_TYPE_NET | INTR_MPSAFE /* | INTR_ENTROPY */,
  139                             NULL, pcf_intr, sc, &sc->intr_cookie);
  140         if (rv) {
  141                 device_printf(dev, "could not setup IRQ\n");
  142                 goto error;
  143         }
  144 
  145         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
  146                 device_printf(dev, "could not allocate iicbus instance\n");
  147 
  148         /* probe and attach the iicbus */
  149         bus_generic_attach(dev);
  150 
  151         return (0);
  152 
  153 error:
  154         if (sc->res_irq != 0) {
  155                 bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq,
  156                                      sc->res_irq);
  157         }
  158         if (sc->res_ioport != 0) {
  159                 bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
  160                                      sc->res_ioport);
  161         }
  162         mtx_destroy(&sc->pcf_lock);
  163         return (rv);
  164 }
  165 
  166 static int
  167 envctrl_detach(device_t dev)
  168 {
  169         struct pcf_softc *sc;
  170         int rv;
  171 
  172         sc = DEVTOSOFTC(dev);
  173 
  174         if ((rv = bus_generic_detach(dev)) != 0)
  175                 return (rv);
  176 
  177         if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
  178                 return (rv);
  179 
  180         if (sc->res_irq != 0) {
  181                 bus_teardown_intr(dev, sc->res_irq, sc->intr_cookie);
  182                 bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq, sc->res_irq);
  183         }
  184 
  185         bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport, sc->res_ioport);
  186         mtx_destroy(&sc->pcf_lock);
  187 
  188         return (0);
  189 }
  190 
  191 DRIVER_MODULE(envctrl, ebus, envctrl_driver, envctrl_devclass, 0, 0);
  192 DRIVER_MODULE(iicbus, envctrl, iicbus_driver, iicbus_devclass, 0, 0);

Cache object: bf8b5b82605d3110ff3c5661b76a57a6


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