1df074184STakanori Watanabe /*-
2df074184STakanori Watanabe  * Copyright (c) 2013 Takanori Watanabe
3df074184STakanori Watanabe  * All rights reserved.
4df074184STakanori Watanabe  *
5df074184STakanori Watanabe  * Redistribution and use in source and binary forms, with or without
6df074184STakanori Watanabe  * modification, are permitted provided that the following conditions
7df074184STakanori Watanabe  * are met:
8df074184STakanori Watanabe  * 1. Redistributions of source code must retain the above copyright
9df074184STakanori Watanabe  *    notice, this list of conditions and the following disclaimer.
10df074184STakanori Watanabe  * 2. Redistributions in binary form must reproduce the above copyright
11df074184STakanori Watanabe  *    notice, this list of conditions and the following disclaimer in the
12df074184STakanori Watanabe  *    documentation and/or other materials provided with the distribution.
13df074184STakanori Watanabe  *
14df074184STakanori Watanabe  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15df074184STakanori Watanabe  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16df074184STakanori Watanabe  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17df074184STakanori Watanabe  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18df074184STakanori Watanabe  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19df074184STakanori Watanabe  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20df074184STakanori Watanabe  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21df074184STakanori Watanabe  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22df074184STakanori Watanabe  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23df074184STakanori Watanabe  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24df074184STakanori Watanabe  * SUCH DAMAGE.
25df074184STakanori Watanabe  */
26df074184STakanori Watanabe 
27df074184STakanori Watanabe #include <sys/cdefs.h>
28df074184STakanori Watanabe __FBSDID("$FreeBSD$");
29df074184STakanori Watanabe 
30df074184STakanori Watanabe #include "opt_acpi.h"
31df074184STakanori Watanabe #include <sys/param.h>
32df074184STakanori Watanabe #include <sys/kernel.h>
33df074184STakanori Watanabe #include <sys/bus.h>
34df074184STakanori Watanabe 
35df074184STakanori Watanabe #include <contrib/dev/acpica/include/acpi.h>
36df074184STakanori Watanabe 
37df074184STakanori Watanabe #include "acpi_if.h"
38df074184STakanori Watanabe #include <sys/module.h>
39df074184STakanori Watanabe #include <dev/acpica/acpivar.h>
40df074184STakanori Watanabe #include <sys/sysctl.h>
41df074184STakanori Watanabe static int sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS);
42df074184STakanori Watanabe 
43df074184STakanori Watanabe 
44df074184STakanori Watanabe static struct acpi_rapidstart_name_list
45df074184STakanori Watanabe {
46df074184STakanori Watanabe 	char *nodename;
47df074184STakanori Watanabe 	char *getmethod;
48df074184STakanori Watanabe 	char *setmethod;
49df074184STakanori Watanabe 	char *comment;
50df074184STakanori Watanabe } acpi_rapidstart_oids[] ={
51df074184STakanori Watanabe 	{"ffs","GFFS","SFFS","Flash Fast Store Flag"},
52df074184STakanori Watanabe 	{"ftv","GFTV","SFTV","Time value"},
53df074184STakanori Watanabe 	{NULL, NULL, NULL, NULL}
54df074184STakanori Watanabe };
55df074184STakanori Watanabe 
56df074184STakanori Watanabe struct acpi_rapidstart_softc {
57df074184STakanori Watanabe 	struct sysctl_ctx_list	*sysctl_ctx;
58df074184STakanori Watanabe 	struct sysctl_oid	*sysctl_tree;
59df074184STakanori Watanabe 
60df074184STakanori Watanabe };
61df074184STakanori Watanabe static char    *rapidstart_ids[] = {"INT3392", NULL};
62df074184STakanori Watanabe static int
63df074184STakanori Watanabe acpi_rapidstart_probe(device_t dev)
64df074184STakanori Watanabe {
65df074184STakanori Watanabe 	if (acpi_disabled("rapidstart") ||
66df074184STakanori Watanabe 	    ACPI_ID_PROBE(device_get_parent(dev), dev, rapidstart_ids) == NULL ||
67df074184STakanori Watanabe 	    device_get_unit(dev) != 0)
68df074184STakanori Watanabe 		return (ENXIO);
69df074184STakanori Watanabe 
70df074184STakanori Watanabe 	device_set_desc(dev, "Intel Rapid Start ACPI device");
71df074184STakanori Watanabe 
72df074184STakanori Watanabe 	return (0);
73df074184STakanori Watanabe 
74df074184STakanori Watanabe }
75df074184STakanori Watanabe 
76df074184STakanori Watanabe static int
77df074184STakanori Watanabe acpi_rapidstart_attach(device_t dev)
78df074184STakanori Watanabe {
79df074184STakanori Watanabe 	struct acpi_rapidstart_softc *sc;
80df074184STakanori Watanabe 	int i;
81df074184STakanori Watanabe 
82df074184STakanori Watanabe 	sc = device_get_softc(dev);
83df074184STakanori Watanabe 
84df074184STakanori Watanabe 	sc->sysctl_ctx = device_get_sysctl_ctx(dev);
85df074184STakanori Watanabe 	sc->sysctl_tree = device_get_sysctl_tree(dev);
86df074184STakanori Watanabe 	for (i = 0 ; acpi_rapidstart_oids[i].nodename != NULL; i++){
87df074184STakanori Watanabe 		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
88df074184STakanori Watanabe 		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
89df074184STakanori Watanabe 		    i, acpi_rapidstart_oids[i].nodename , CTLTYPE_INT |
90df074184STakanori Watanabe 		    ((acpi_rapidstart_oids[i].setmethod)? CTLFLAG_RW: CTLFLAG_RD),
91df074184STakanori Watanabe 		    dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
92df074184STakanori Watanabe 		    acpi_rapidstart_oids[i].comment);
93df074184STakanori Watanabe 	}
94df074184STakanori Watanabe 	return (0);
95df074184STakanori Watanabe }
96df074184STakanori Watanabe 
97df074184STakanori Watanabe static int
98df074184STakanori Watanabe sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS)
99df074184STakanori Watanabe {
100df074184STakanori Watanabe 	device_t	dev = arg1;
101df074184STakanori Watanabe 	int 	function = oidp->oid_arg2;
102df074184STakanori Watanabe 	int		error = 0, val;
103df074184STakanori Watanabe 
104df074184STakanori Watanabe 	acpi_GetInteger(acpi_get_handle(dev),
105df074184STakanori Watanabe 	    acpi_rapidstart_oids[function].getmethod, &val);
106df074184STakanori Watanabe 	error = sysctl_handle_int(oidp, &val, 0, req);
107df074184STakanori Watanabe 	if (error || !req->newptr || !acpi_rapidstart_oids[function].setmethod)
108df074184STakanori Watanabe 		return (error);
109df074184STakanori Watanabe 	acpi_SetInteger(acpi_get_handle(dev),
110df074184STakanori Watanabe 	    acpi_rapidstart_oids[function].setmethod, val);
111df074184STakanori Watanabe 	return (0);
112df074184STakanori Watanabe }
113df074184STakanori Watanabe 
114df074184STakanori Watanabe static device_method_t acpi_rapidstart_methods[] = {
115df074184STakanori Watanabe 	/* Device interface */
116df074184STakanori Watanabe 	DEVMETHOD(device_probe, acpi_rapidstart_probe),
117df074184STakanori Watanabe 	DEVMETHOD(device_attach, acpi_rapidstart_attach),
118df074184STakanori Watanabe 
119df074184STakanori Watanabe 	DEVMETHOD_END
120df074184STakanori Watanabe };
121df074184STakanori Watanabe 
122df074184STakanori Watanabe static driver_t	acpi_rapidstart_driver = {
123df074184STakanori Watanabe 	"acpi_rapidstart",
124df074184STakanori Watanabe 	acpi_rapidstart_methods,
125df074184STakanori Watanabe 	sizeof(struct acpi_rapidstart_softc),
126df074184STakanori Watanabe };
127df074184STakanori Watanabe 
128df074184STakanori Watanabe static devclass_t acpi_rapidstart_devclass;
129df074184STakanori Watanabe 
130df074184STakanori Watanabe DRIVER_MODULE(acpi_rapidstart, acpi, acpi_rapidstart_driver, acpi_rapidstart_devclass,
131df074184STakanori Watanabe 	      0, 0);
132df074184STakanori Watanabe MODULE_DEPEND(acpi_rapidstart, acpi, 1, 1, 1);
133df074184STakanori Watanabe 
134