lasi.c revision 1.8
1/* $OpenBSD: lasi.c,v 1.8 2002/03/14 01:26:31 millert Exp $ */ 2 3/* 4 * Copyright (c) 1998-2002 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Michael Shalayeff. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF MIND, 27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#undef LASIDEBUG 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/device.h> 38#include <sys/reboot.h> 39 40#include <machine/bus.h> 41#include <machine/iomod.h> 42#include <machine/autoconf.h> 43 44#include <hppa/dev/cpudevs.h> 45 46#include <hppa/gsc/gscbusvar.h> 47 48struct lasi_hwr { 49 u_int32_t lasi_power; 50#define LASI_BLINK 0x01 51#define LASI_ON 0x02 52 u_int32_t lasi_error; 53 u_int32_t lasi_version; 54 u_int32_t lasi_reset; 55 u_int32_t lasi_arbmask; 56}; 57 58struct lasi_trs { 59 u_int32_t lasi_irr; /* int requset register */ 60 u_int32_t lasi_imr; /* int mask register */ 61 u_int32_t lasi_ipr; /* int pending register */ 62 u_int32_t lasi_icr; /* int command? register */ 63 u_int32_t lasi_iar; /* int acquire? register */ 64}; 65 66struct lasi_softc { 67 struct device sc_dev; 68 struct gscbus_ic sc_ic; 69 70 struct lasi_hwr volatile *sc_hw; 71 struct lasi_trs volatile *sc_trs; 72 struct gsc_attach_args ga; /* for deferred attach */ 73}; 74 75int lasimatch(struct device *, void *, void *); 76void lasiattach(struct device *, struct device *, void *); 77void lasi_gsc_attach(struct device *); 78 79struct cfattach lasi_ca = { 80 sizeof(struct lasi_softc), lasimatch, lasiattach 81}; 82 83struct cfdriver lasi_cd = { 84 NULL, "lasi", DV_DULL 85}; 86 87void lasi_intr_establish(void *v, u_int32_t mask); 88void lasi_intr_disestablish(void *v, u_int32_t mask); 89u_int32_t lasi_intr_check(void *v); 90void lasi_intr_ack(void *v, u_int32_t mask); 91void lasi_cold_hook(int on); 92 93 94int 95lasimatch(parent, cfdata, aux) 96 struct device *parent; 97 void *cfdata; 98 void *aux; 99{ 100 register struct confargs *ca = aux; 101 /* register struct cfdata *cf = cfdata; */ 102 103 if (ca->ca_type.iodc_type != HPPA_TYPE_BHA || 104 ca->ca_type.iodc_sv_model != HPPA_BHA_LASI) 105 return 0; 106 107 return 1; 108} 109 110void 111lasiattach(parent, self, aux) 112 struct device *parent; 113 struct device *self; 114 void *aux; 115{ 116 register struct confargs *ca = aux; 117 register struct lasi_softc *sc = (struct lasi_softc *)self; 118 bus_space_handle_t ioh; 119 int s, in; 120 121 if (bus_space_map(ca->ca_iot, ca->ca_hpa + 0xc000, 122 IOMOD_HPASIZE, 0, &ioh)) { 123#ifdef DEBUG 124 printf("lasiattach: can't map IO space\n"); 125#endif 126 return; 127 } 128 129 sc->sc_trs = (struct lasi_trs *)ca->ca_hpa; 130 sc->sc_hw = (struct lasi_hwr *)(ca->ca_hpa + 0xc000); 131 132 /* XXX should we reset the chip here? */ 133 134 printf (": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4, 135 sc->sc_hw->lasi_version & 0xf); 136 137 /* interrupts guts */ 138 s = splhigh(); 139 sc->sc_trs->lasi_iar = cpu_gethpa(0) | (31 - ca->ca_irq); 140 sc->sc_trs->lasi_icr = 0; 141 sc->sc_trs->lasi_imr = ~0U; 142 in = sc->sc_trs->lasi_irr; 143 sc->sc_trs->lasi_imr = 0; 144 splx(s); 145 146 sc->sc_ic.gsc_type = gsc_lasi; 147 sc->sc_ic.gsc_dv = sc; 148 sc->sc_ic.gsc_intr_establish = lasi_intr_establish; 149 sc->sc_ic.gsc_intr_disestablish = lasi_intr_disestablish; 150 sc->sc_ic.gsc_intr_check = lasi_intr_check; 151 sc->sc_ic.gsc_intr_ack = lasi_intr_ack; 152 153 sc->ga.ga_ca = *ca; /* clone from us */ 154 if (sc->sc_dev.dv_unit) 155 config_defer(self, lasi_gsc_attach); 156 else { 157 extern void (*cold_hook)(int); 158 159 lasi_gsc_attach(self); 160 cold_hook = lasi_cold_hook; 161 } 162} 163 164void 165lasi_gsc_attach(self) 166 struct device *self; 167{ 168 struct lasi_softc *sc = (struct lasi_softc *)self; 169 170 sc->ga.ga_name = "gsc"; 171 sc->ga.ga_ic = &sc->sc_ic; 172 config_found(self, &sc->ga, gscprint); 173} 174 175void 176lasi_cold_hook(on) 177 int on; 178{ 179 register struct lasi_softc *sc = lasi_cd.cd_devs[0]; 180 181 if (!sc) 182 return; 183 184 switch (on) { 185 case HPPA_COLD_COLD: 186 sc->sc_hw->lasi_power = LASI_BLINK; 187 break; 188 case HPPA_COLD_HOT: 189 sc->sc_hw->lasi_power = 0; 190 break; 191 case HPPA_COLD_OFF: 192 sc->sc_hw->lasi_power = LASI_BLINK; 193 break; 194 } 195} 196 197void 198lasi_intr_establish(v, mask) 199 void *v; 200 u_int32_t mask; 201{ 202 register struct lasi_softc *sc = v; 203 204 sc->sc_trs->lasi_imr |= mask; 205} 206 207void 208lasi_intr_disestablish(v, mask) 209 void *v; 210 u_int32_t mask; 211{ 212 register struct lasi_softc *sc = v; 213 214 sc->sc_trs->lasi_imr &= ~mask; 215} 216 217u_int32_t 218lasi_intr_check(v) 219 void *v; 220{ 221 register struct lasi_softc *sc = v; 222 register u_int32_t irr, imr, ipr; 223 224 imr = sc->sc_trs->lasi_imr; 225 ipr = sc->sc_trs->lasi_ipr; 226 irr = sc->sc_trs->lasi_irr; 227 sc->sc_trs->lasi_irr = irr; 228 229#ifdef LASIDEBUG 230 printf ("%s: imr=0x%x, irr=0x%x, ipr=0x%x, iar=0x%x, icr=0x%x\n", 231 sc->sc_dev.dv_xname, imr, irr, ipr, 232 sc->sc_trs->lasi_iar, sc->sc_trs->lasi_icr); 233#endif 234 235 return irr; 236} 237 238void 239lasi_intr_ack(v, mask) 240 void *v; 241 u_int32_t mask; 242{ 243 register struct lasi_softc *sc = v; 244 245 sc->sc_trs->lasi_imr |= mask; 246} 247