diff --git a/sys/arch/sparc/dev/zs.c b/sys/arch/sparc/dev/zs.c index 0a6998358ff0..3a211c64c305 100644 --- a/sys/arch/sparc/dev/zs.c +++ b/sys/arch/sparc/dev/zs.c @@ -1,4 +1,4 @@ -/* $NetBSD: zs.c,v 1.74 2000/03/06 21:36:11 thorpej Exp $ */ +/* $NetBSD: zs.c,v 1.75 2000/03/14 21:20:51 jdc Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -71,6 +71,7 @@ #include #include +#include #include #include "kbd.h" /* NKBD */ @@ -186,6 +187,10 @@ static struct intrhand levelsoft = { zssoft }; static int zs_get_speed __P((struct zs_chanstate *)); +/* Power management hooks */ +int zs_enable __P((struct zs_chanstate *)); +void zs_disable __P((struct zs_chanstate *)); + /* * Is the zs chip present? @@ -258,6 +263,8 @@ zs_attach_obio(parent, self, aux) if (uoba->uoba_isobio4 == 0) { struct sbus_attach_args *sa = &uoba->uoba_sbus; void *va; + struct zs_chanstate *cs; + int channel; if (sa->sa_nintr == 0) { printf(" no interrupt lines\n"); @@ -284,6 +291,19 @@ zs_attach_obio(parent, self, aux) va = (void *)bh; } + /* + * Check if power state can be set, e.g. Tadpole 3GX + */ + if (getpropint(sa->sa_node, "pwr-on-auxio2", 0)) + { + printf (" powered via auxio2"); + for (channel = 0; channel < 2; channel++) { + cs = &zsc->zsc_cs_store[channel]; + cs->enable = zs_enable; + cs->disable = zs_disable; + } + } + zsc->zsc_bustag = sa->sa_bustag; zsc->zsc_dmatag = sa->sa_dmatag; zs_attach(zsc, va, sa->sa_pri); @@ -1074,3 +1094,24 @@ setup_console: zs_kgdb_init(); #endif } + +/* + * Power management hooks for zsopen() and zsclose(). + * We use them to power on/off the ports, if necessary. + */ +int +zs_enable(cs) + struct zs_chanstate *cs; +{ + auxiotwoserialendis (ZS_ENABLE); + cs->enabled = 1; + return(0); +} + +void +zs_disable(cs) + struct zs_chanstate *cs; +{ + auxiotwoserialendis (ZS_DISABLE); + cs->enabled = 0; +} diff --git a/sys/dev/ic/z8530sc.h b/sys/dev/ic/z8530sc.h index 73a6fce4f267..2d547298669c 100644 --- a/sys/dev/ic/z8530sc.h +++ b/sys/dev/ic/z8530sc.h @@ -1,4 +1,4 @@ -/* $NetBSD: z8530sc.h,v 1.12 1999/03/27 01:22:36 wrstuden Exp $ */ +/* $NetBSD: z8530sc.h,v 1.13 2000/03/14 21:20:52 jdc Exp $ */ /* * Copyright (c) 1994 Gordon W. Ross @@ -113,6 +113,12 @@ struct zs_chanstate { char cs_softreq; /* need soft interrupt call */ char cs_spare1; /* (for skippy :) */ + + /* power management hooks */ + int (*enable) __P((struct zs_chanstate *)); + void (*disable) __P((struct zs_chanstate *)); + int enabled; + /* MD code might define a larger variant of this. */ }; diff --git a/sys/dev/ic/z8530tty.c b/sys/dev/ic/z8530tty.c index 2dd01f303e9e..8a2bdfa2c9ab 100644 --- a/sys/dev/ic/z8530tty.c +++ b/sys/dev/ic/z8530tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: z8530tty.c,v 1.62 1999/11/04 05:33:59 jonathan Exp $ */ +/* $NetBSD: z8530tty.c,v 1.63 2000/03/14 21:20:52 jdc Exp $ */ /*- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 @@ -325,7 +325,10 @@ zstty_attach(parent, self, aux) zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf; zst->zst_rbavail = zstty_rbuf_size; - /* XXX - Do we need an MD hook here? */ + /* if there are no enable/disable functions, assume the device + is always enabled */ + if (!cs->enable) + cs->enabled = 1; /* * Hardware init @@ -435,6 +438,15 @@ zs_shutdown(zst) zs_write_reg(cs, 1, cs->cs_creg[1]); } + /* Call the power management hook. */ + if (cs->disable) { +#ifdef DIAGNOSTIC + if (!cs->enabled) + panic("zs_shutdown: not enabled?"); +#endif + (*cs->disable)(zst->zst_cs); + } + splx(s); } @@ -482,6 +494,17 @@ zsopen(dev, flags, mode, p) tp->t_dev = dev; + /* Call the power management hook. */ + if (cs->enable) { + if ((*cs->enable)(cs)) { + splx(s2); + splx(s); + printf("%s: device enable failed\n", + zst->zst_dev.dv_xname); + return (EIO); + } + } + /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS.