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++){
87f0188618SHans Petter Selasky 		if (acpi_rapidstart_oids[i].setmethod != NULL) {
88df074184STakanori Watanabe 			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
89df074184STakanori Watanabe 			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
90f0188618SHans Petter Selasky 			    i, acpi_rapidstart_oids[i].nodename,
91f0188618SHans Petter Selasky 			    CTLTYPE_INT | CTLFLAG_RW,
92df074184STakanori Watanabe 			    dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
93df074184STakanori Watanabe 			    acpi_rapidstart_oids[i].comment);
94f0188618SHans Petter Selasky 		} else {
95f0188618SHans Petter Selasky 			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
96f0188618SHans Petter Selasky 			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
97f0188618SHans Petter Selasky 			    i, acpi_rapidstart_oids[i].nodename,
98f0188618SHans Petter Selasky 			    CTLTYPE_INT | CTLFLAG_RD,
99f0188618SHans Petter Selasky 			    dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
100f0188618SHans Petter Selasky 			    acpi_rapidstart_oids[i].comment);
101f0188618SHans Petter Selasky 		}
102df074184STakanori Watanabe 	}
103df074184STakanori Watanabe 	return (0);
104df074184STakanori Watanabe }
105df074184STakanori Watanabe 
106df074184STakanori Watanabe static int
107df074184STakanori Watanabe sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS)
108df074184STakanori Watanabe {
109df074184STakanori Watanabe 	device_t	dev = arg1;
110df074184STakanori Watanabe 	int 	function = oidp->oid_arg2;
111df074184STakanori Watanabe 	int		error = 0, val;
112df074184STakanori Watanabe 
113df074184STakanori Watanabe 	acpi_GetInteger(acpi_get_handle(dev),
114df074184STakanori Watanabe 	    acpi_rapidstart_oids[function].getmethod, &val);
115df074184STakanori Watanabe 	error = sysctl_handle_int(oidp, &val, 0, req);
116df074184STakanori Watanabe 	if (error || !req->newptr || !acpi_rapidstart_oids[function].setmethod)
117df074184STakanori Watanabe 		return (error);
118df074184STakanori Watanabe 	acpi_SetInteger(acpi_get_handle(dev),
119df074184STakanori Watanabe 	    acpi_rapidstart_oids[function].setmethod, val);
120df074184STakanori Watanabe 	return (0);
121df074184STakanori Watanabe }
122df074184STakanori Watanabe 
123df074184STakanori Watanabe static device_method_t acpi_rapidstart_methods[] = {
124df074184STakanori Watanabe 	/* Device interface */
125df074184STakanori Watanabe 	DEVMETHOD(device_probe, acpi_rapidstart_probe),
126df074184STakanori Watanabe 	DEVMETHOD(device_attach, acpi_rapidstart_attach),
127df074184STakanori Watanabe 
128df074184STakanori Watanabe 	DEVMETHOD_END
129df074184STakanori Watanabe };
130df074184STakanori Watanabe 
131df074184STakanori Watanabe static driver_t	acpi_rapidstart_driver = {
132df074184STakanori Watanabe 	"acpi_rapidstart",
133df074184STakanori Watanabe 	acpi_rapidstart_methods,
134df074184STakanori Watanabe 	sizeof(struct acpi_rapidstart_softc),
135df074184STakanori Watanabe };
136df074184STakanori Watanabe 
137df074184STakanori Watanabe static devclass_t acpi_rapidstart_devclass;
138df074184STakanori Watanabe 
139df074184STakanori Watanabe DRIVER_MODULE(acpi_rapidstart, acpi, acpi_rapidstart_driver, acpi_rapidstart_devclass,
140df074184STakanori Watanabe 	      0, 0);
141df074184STakanori Watanabe MODULE_DEPEND(acpi_rapidstart, acpi, 1, 1, 1);
142df074184STakanori Watanabe 
143