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 #include "opt_acpi.h"
29df074184STakanori Watanabe #include <sys/param.h>
30df074184STakanori Watanabe #include <sys/kernel.h>
31df074184STakanori Watanabe #include <sys/bus.h>
32df074184STakanori Watanabe
33df074184STakanori Watanabe #include <contrib/dev/acpica/include/acpi.h>
34df074184STakanori Watanabe
35df074184STakanori Watanabe #include "acpi_if.h"
36df074184STakanori Watanabe #include <sys/module.h>
37df074184STakanori Watanabe #include <dev/acpica/acpivar.h>
38df074184STakanori Watanabe #include <sys/sysctl.h>
39df074184STakanori Watanabe static int sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS);
40df074184STakanori Watanabe
41df074184STakanori Watanabe static struct acpi_rapidstart_name_list
42df074184STakanori Watanabe {
43df074184STakanori Watanabe char *nodename;
44df074184STakanori Watanabe char *getmethod;
45df074184STakanori Watanabe char *setmethod;
46df074184STakanori Watanabe char *comment;
47df074184STakanori Watanabe } acpi_rapidstart_oids[] ={
48df074184STakanori Watanabe {"ffs","GFFS","SFFS","Flash Fast Store Flag"},
49df074184STakanori Watanabe {"ftv","GFTV","SFTV","Time value"},
50df074184STakanori Watanabe {NULL, NULL, NULL, NULL}
51df074184STakanori Watanabe };
52df074184STakanori Watanabe
53df074184STakanori Watanabe struct acpi_rapidstart_softc {
54df074184STakanori Watanabe struct sysctl_ctx_list *sysctl_ctx;
55df074184STakanori Watanabe struct sysctl_oid *sysctl_tree;
56df074184STakanori Watanabe
57df074184STakanori Watanabe };
58df074184STakanori Watanabe static char *rapidstart_ids[] = {"INT3392", NULL};
59df074184STakanori Watanabe static int
acpi_rapidstart_probe(device_t dev)60df074184STakanori Watanabe acpi_rapidstart_probe(device_t dev)
61df074184STakanori Watanabe {
625efca36fSTakanori Watanabe int rv;
635efca36fSTakanori Watanabe
64df074184STakanori Watanabe if (acpi_disabled("rapidstart") ||
65df074184STakanori Watanabe device_get_unit(dev) != 0)
66df074184STakanori Watanabe return (ENXIO);
675efca36fSTakanori Watanabe rv = ACPI_ID_PROBE(device_get_parent(dev), dev, rapidstart_ids, NULL);
685efca36fSTakanori Watanabe if (rv <= 0)
69df074184STakanori Watanabe device_set_desc(dev, "Intel Rapid Start ACPI device");
70df074184STakanori Watanabe
715efca36fSTakanori Watanabe return (rv);
72df074184STakanori Watanabe
73df074184STakanori Watanabe }
74df074184STakanori Watanabe
75df074184STakanori Watanabe static int
acpi_rapidstart_attach(device_t dev)76df074184STakanori Watanabe acpi_rapidstart_attach(device_t dev)
77df074184STakanori Watanabe {
78df074184STakanori Watanabe struct acpi_rapidstart_softc *sc;
79df074184STakanori Watanabe int i;
80df074184STakanori Watanabe
81df074184STakanori Watanabe sc = device_get_softc(dev);
82df074184STakanori Watanabe
83df074184STakanori Watanabe sc->sysctl_ctx = device_get_sysctl_ctx(dev);
84df074184STakanori Watanabe sc->sysctl_tree = device_get_sysctl_tree(dev);
85df074184STakanori Watanabe for (i = 0 ; acpi_rapidstart_oids[i].nodename != NULL; i++){
86f0188618SHans Petter Selasky if (acpi_rapidstart_oids[i].setmethod != NULL) {
87df074184STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
88df074184STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
89f0188618SHans Petter Selasky i, acpi_rapidstart_oids[i].nodename,
906237a1ccSAlexander Motin CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
91df074184STakanori Watanabe dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
92df074184STakanori Watanabe acpi_rapidstart_oids[i].comment);
93f0188618SHans Petter Selasky } else {
94f0188618SHans Petter Selasky SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
95f0188618SHans Petter Selasky SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
96f0188618SHans Petter Selasky i, acpi_rapidstart_oids[i].nodename,
976237a1ccSAlexander Motin CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
98f0188618SHans Petter Selasky dev, i, sysctl_acpi_rapidstart_gen_handler, "I",
99f0188618SHans Petter Selasky acpi_rapidstart_oids[i].comment);
100f0188618SHans Petter Selasky }
101df074184STakanori Watanabe }
102df074184STakanori Watanabe return (0);
103df074184STakanori Watanabe }
104df074184STakanori Watanabe
105df074184STakanori Watanabe static int
sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS)106df074184STakanori Watanabe sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS)
107df074184STakanori Watanabe {
108df074184STakanori Watanabe device_t dev = arg1;
109df074184STakanori Watanabe int function = oidp->oid_arg2;
110df074184STakanori Watanabe int error = 0, val;
111df074184STakanori Watanabe
112df074184STakanori Watanabe acpi_GetInteger(acpi_get_handle(dev),
113df074184STakanori Watanabe acpi_rapidstart_oids[function].getmethod, &val);
114df074184STakanori Watanabe error = sysctl_handle_int(oidp, &val, 0, req);
115df074184STakanori Watanabe if (error || !req->newptr || !acpi_rapidstart_oids[function].setmethod)
116df074184STakanori Watanabe return (error);
117df074184STakanori Watanabe acpi_SetInteger(acpi_get_handle(dev),
118df074184STakanori Watanabe acpi_rapidstart_oids[function].setmethod, val);
119df074184STakanori Watanabe return (0);
120df074184STakanori Watanabe }
121df074184STakanori Watanabe
122df074184STakanori Watanabe static device_method_t acpi_rapidstart_methods[] = {
123df074184STakanori Watanabe /* Device interface */
124df074184STakanori Watanabe DEVMETHOD(device_probe, acpi_rapidstart_probe),
125df074184STakanori Watanabe DEVMETHOD(device_attach, acpi_rapidstart_attach),
126df074184STakanori Watanabe
127df074184STakanori Watanabe DEVMETHOD_END
128df074184STakanori Watanabe };
129df074184STakanori Watanabe
130df074184STakanori Watanabe static driver_t acpi_rapidstart_driver = {
131df074184STakanori Watanabe "acpi_rapidstart",
132df074184STakanori Watanabe acpi_rapidstart_methods,
133df074184STakanori Watanabe sizeof(struct acpi_rapidstart_softc),
134df074184STakanori Watanabe };
135df074184STakanori Watanabe
136*90161e72SJohn Baldwin DRIVER_MODULE(acpi_rapidstart, acpi, acpi_rapidstart_driver, 0, 0);
137df074184STakanori Watanabe MODULE_DEPEND(acpi_rapidstart, acpi, 1, 1, 1);
138