1110285Snyan/*- 2110285Snyan * Copyright (c) 2000 KIYOHARA Takashi <kiyohara@kk.iij4u.ne.jp> 3110329Stakawata * Copyright (c) 2000 Takanori Watanabe <takawata@jp.FreeBSD.org> 4110333Snyan * All rights reserved. 5110285Snyan * 6110285Snyan * Redistribution and use in source and binary forms, with or without 7110285Snyan * modification, are permitted provided that the following conditions 8110285Snyan * are met: 9110285Snyan * 1. Redistributions of source code must retain the above copyright 10110285Snyan * notice, this list of conditions and the following disclaimer. 11110285Snyan * 2. Redistributions in binary form must reproduce the above copyright 12110285Snyan * notice, this list of conditions and the following disclaimer in the 13110285Snyan * documentation and/or other materials provided with the distribution. 14110285Snyan * 15110285Snyan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16110285Snyan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17110285Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18110285Snyan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19110285Snyan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20110285Snyan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21110285Snyan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22110285Snyan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23110285Snyan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24110285Snyan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25110333Snyan * SUCH DAMAGE. 26110285Snyan * 27110285Snyan * $FreeBSD$ 28110285Snyan */ 29110285Snyan 30110285Snyan#include <sys/param.h> 31110285Snyan#include <sys/systm.h> 32110285Snyan#include <sys/bus.h> 33110285Snyan#include <sys/eventhandler.h> 34110285Snyan#include <sys/kernel.h> 35110285Snyan#include <sys/module.h> 36110285Snyan#include <sys/reboot.h> 37110285Snyan 38110285Snyan#include <machine/bus.h> 39110285Snyan#include <machine/resource.h> 40110285Snyan#include <sys/rman.h> 41110285Snyan 42110285Snyan#include <pc98/pc98/canbusvars.h> 43110285Snyan#include "canbus_if.h" 44110285Snyan 45110285Snyan 46110285Snyan/* canbepm softc */ 47110285Snyanstruct canbepm_softc { 48110285Snyan device_t canbepm_dev; /* canbepm device */ 49110285Snyan 50110285Snyan eventhandler_tag canbepm_tag; /* event handler tag */ 51110285Snyan}; 52110285Snyan 53110285Snyan 54110285Snyanstatic void canbepm_soft_off (void *, int); 55110285Snyanstatic void canbepm_identify (driver_t *, device_t); 56110285Snyanstatic int canbepm_probe (device_t); 57110285Snyanstatic int canbepm_attach (device_t); 58110285Snyanstatic int canbepm_detach (device_t); 59110285Snyan 60110285Snyan 61110285Snyanstatic device_method_t canbepm_methods[] = { 62110285Snyan DEVMETHOD(device_identify, canbepm_identify), 63110285Snyan DEVMETHOD(device_probe, canbepm_probe), 64110285Snyan DEVMETHOD(device_attach, canbepm_attach), 65110285Snyan DEVMETHOD(device_detach, canbepm_detach), 66110285Snyan {0, 0} 67110285Snyan}; 68110285Snyan 69110285Snyanstatic driver_t canbepm_driver = { 70110285Snyan "canbepm", 71110285Snyan canbepm_methods, 72110285Snyan sizeof(struct canbepm_softc), 73110285Snyan}; 74110285Snyan 75110285Snyandevclass_t canbepm_devclass; 76110285SnyanDRIVER_MODULE(canbepm, canbus, canbepm_driver, canbepm_devclass, 0, 0); 77110285SnyanMODULE_DEPEND(canbepm, canbus, 1, 1, 1); 78110285Snyan 79110285Snyan 80110285Snyanstatic void 81110285Snyancanbepm_soft_off (void *data, int howto) 82110285Snyan{ 83110285Snyan struct canbepm_softc *sc = data; 84110285Snyan u_int8_t poweroff_data[] = CANBE_POWEROFF_DATA; 85110285Snyan 86110285Snyan if (!(howto & RB_POWEROFF)) 87110285Snyan return; 88110285Snyan 89110285Snyan CANBUS_WRITE_MULTI(device_get_parent(sc->canbepm_dev), sc->canbepm_dev, 90110285Snyan CANBE_POWER_CTRL, sizeof (poweroff_data), poweroff_data); 91110285Snyan} 92110285Snyan 93110285Snyan 94110285Snyanstatic void 95110285Snyancanbepm_identify(driver_t *drv, device_t parent) 96110285Snyan{ 97110285Snyan if (device_find_child(parent, "canbepm", 0) == NULL) { 98110285Snyan if (BUS_ADD_CHILD(parent, 33, "canbepm", 0) == NULL) 99110285Snyan device_printf(parent, "canbepm cannot attach\n"); 100110285Snyan } 101110285Snyan} 102110285Snyan 103110285Snyan 104110285Snyanstatic int 105110285Snyancanbepm_probe(device_t dev) 106110285Snyan{ 107110285Snyan device_set_desc(dev, "CanBe Power Management Controller"); 108110285Snyan 109110285Snyan return (0); 110110285Snyan} 111110285Snyan 112110285Snyanstatic int 113110285Snyancanbepm_attach(device_t dev) 114110285Snyan{ 115110285Snyan struct canbepm_softc *sc = device_get_softc(dev); 116110285Snyan 117110285Snyan /* eventhandler regist */ 118110285Snyan sc->canbepm_tag = EVENTHANDLER_REGISTER( 119110285Snyan shutdown_final, canbepm_soft_off, sc, SHUTDOWN_PRI_LAST); 120110285Snyan 121110285Snyan sc->canbepm_dev = dev; 122110285Snyan 123110285Snyan return (0); 124110285Snyan} 125110285Snyan 126110285Snyan 127110285Snyanstatic int 128110285Snyancanbepm_detach(device_t dev) 129110285Snyan{ 130110285Snyan struct canbepm_softc *sc = device_get_softc(dev); 131110285Snyan 132110285Snyan /* eventhandler deregist */ 133110285Snyan EVENTHANDLER_DEREGISTER(shutdown_final, sc->canbepm_tag); 134110285Snyan BUS_CHILD_DETACHED(device_get_parent(dev), dev); 135110285Snyan 136110285Snyan return (0); 137110285Snyan} 138