canbepm.c revision 110285
1107590Sobrien/*-
2169689Skan * Copyright (c) 2000 Takanori Watanabe <wnabe@par.odn.ne.jp>
3132718Skan * Copyright (c) 2000 KIYOHARA Takashi <kiyohara@kk.iij4u.ne.jp>
4107590Sobrien *
5107590Sobrien * Redistribution and use in source and binary forms, with or without
6107590Sobrien * modification, are permitted provided that the following conditions
7132718Skan * are met:
8107590Sobrien * 1. Redistributions of source code must retain the above copyright
9132718Skan *    notice, this list of conditions and the following disclaimer.
10132718Skan * 2. Redistributions in binary form must reproduce the above copyright
11132718Skan *    notice, this list of conditions and the following disclaimer in the
12132718Skan *    documentation and/or other materials provided with the distribution.
13107590Sobrien *
14132718Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15132718Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16132718Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17132718Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18107590Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19107590Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20132718Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21169689Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22169689Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23107590Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24107590Sobrien *
25107590Sobrien * $FreeBSD: head/sys/pc98/pc98/canbepm.c 110285 2003-02-03 14:46:26Z nyan $
26132718Skan */
27132718Skan
28107590Sobrien#include <sys/param.h>
29107590Sobrien#include <sys/systm.h>
30107590Sobrien#include <sys/bus.h>
31107590Sobrien#include <sys/eventhandler.h>
32107590Sobrien#include <sys/kernel.h>
33107590Sobrien#include <sys/module.h>
34107590Sobrien#include <sys/reboot.h>
35107590Sobrien
36107590Sobrien#include <machine/bus.h>
37107590Sobrien#include <machine/resource.h>
38107590Sobrien#include <sys/rman.h>
39107590Sobrien
40107590Sobrien#include <pc98/pc98/canbusvars.h>
41107590Sobrien#include "canbus_if.h"
42107590Sobrien
43107590Sobrien
44107590Sobrien/* canbepm softc */
45107590Sobrienstruct canbepm_softc {
46107590Sobrien	device_t canbepm_dev;			/* canbepm device */
47107590Sobrien
48107590Sobrien	eventhandler_tag canbepm_tag;		/* event handler tag */
49107590Sobrien};
50107590Sobrien
51117395Skan
52117395Skanstatic void	canbepm_soft_off (void *, int);
53169689Skanstatic void	canbepm_identify (driver_t *, device_t);
54107590Sobrienstatic int	canbepm_probe (device_t);
55107590Sobrienstatic int	canbepm_attach (device_t);
56169689Skanstatic int	canbepm_detach (device_t);
57132718Skan
58169689Skan
59169689Skanstatic device_method_t canbepm_methods[] = {
60169689Skan	DEVMETHOD(device_identify,	canbepm_identify),
61169689Skan	DEVMETHOD(device_probe,		canbepm_probe),
62169689Skan	DEVMETHOD(device_attach,	canbepm_attach),
63169689Skan	DEVMETHOD(device_detach,	canbepm_detach),
64169689Skan	{0, 0}
65169689Skan};
66169689Skan
67169689Skanstatic driver_t canbepm_driver = {
68169689Skan	"canbepm",
69169689Skan	canbepm_methods,
70169689Skan	sizeof(struct canbepm_softc),
71169689Skan};
72169689Skan
73169689Skandevclass_t canbepm_devclass;
74169689SkanDRIVER_MODULE(canbepm, canbus, canbepm_driver, canbepm_devclass, 0, 0);
75169689SkanMODULE_DEPEND(canbepm, canbus, 1, 1, 1);
76169689Skan
77169689Skan
78169689Skanstatic void
79169689Skancanbepm_soft_off (void *data, int howto)
80169689Skan{
81169689Skan	struct canbepm_softc *sc = data;
82169689Skan	u_int8_t poweroff_data[] = CANBE_POWEROFF_DATA;
83169689Skan
84169689Skan	if (!(howto & RB_POWEROFF))
85169689Skan		return;
86169689Skan
87169689Skan	CANBUS_WRITE_MULTI(device_get_parent(sc->canbepm_dev), sc->canbepm_dev,
88169689Skan	    CANBE_POWER_CTRL, sizeof (poweroff_data), poweroff_data);
89169689Skan}
90169689Skan
91169689Skan
92169689Skanstatic void
93169689Skancanbepm_identify(driver_t *drv, device_t parent)
94169689Skan{
95132718Skan	if (device_find_child(parent, "canbepm", 0) == NULL) {
96169689Skan		if (BUS_ADD_CHILD(parent, 33, "canbepm", 0) == NULL)
97132718Skan			device_printf(parent, "canbepm cannot attach\n");
98169689Skan	}
99169689Skan}
100169689Skan
101169689Skan
102169689Skanstatic int
103169689Skancanbepm_probe(device_t dev)
104169689Skan{
105169689Skan	device_set_desc(dev, "CanBe Power Management Controller");
106169689Skan
107169689Skan	return (0);
108169689Skan}
109169689Skan
110169689Skanstatic int
111169689Skancanbepm_attach(device_t dev)
112169689Skan{
113169689Skan	struct canbepm_softc *sc = device_get_softc(dev);
114169689Skan
115169689Skan	/* eventhandler regist */
116169689Skan	sc->canbepm_tag = EVENTHANDLER_REGISTER(
117169689Skan	    shutdown_final, canbepm_soft_off, sc, SHUTDOWN_PRI_LAST);
118169689Skan
119169689Skan	sc->canbepm_dev = dev;
120169689Skan
121169689Skan	return (0);
122169689Skan}
123169689Skan
124169689Skan
125169689Skanstatic int
126169689Skancanbepm_detach(device_t dev)
127169689Skan{
128169689Skan	struct canbepm_softc *sc = device_get_softc(dev);
129169689Skan
130169689Skan	/* eventhandler deregist */
131169689Skan	EVENTHANDLER_DEREGISTER(shutdown_final, sc->canbepm_tag);
132107590Sobrien	BUS_CHILD_DETACHED(device_get_parent(dev), dev);
133169689Skan
134169689Skan	return (0);
135169689Skan}
136169689Skan