xref: /netbsd/sys/dev/acpi/apple_smc_acpi.c (revision e9607ed6)
1*e9607ed6Sthorpej /*	$NetBSD: apple_smc_acpi.c,v 1.5 2021/01/29 15:49:55 thorpej Exp $	*/
2681af2a9Sriastradh 
3681af2a9Sriastradh /*
4681af2a9Sriastradh  * Apple System Management Controller: ACPI Attachment
5681af2a9Sriastradh  */
6681af2a9Sriastradh 
7681af2a9Sriastradh /*-
8b9d5e7eaSriastradh  * Copyright (c) 2013 The NetBSD Foundation, Inc.
9681af2a9Sriastradh  * All rights reserved.
10681af2a9Sriastradh  *
11b9d5e7eaSriastradh  * This code is derived from software contributed to The NetBSD Foundation
12b9d5e7eaSriastradh  * by Taylor R. Campbell.
13b9d5e7eaSriastradh  *
14681af2a9Sriastradh  * Redistribution and use in source and binary forms, with or without
15681af2a9Sriastradh  * modification, are permitted provided that the following conditions
16681af2a9Sriastradh  * are met:
17681af2a9Sriastradh  * 1. Redistributions of source code must retain the above copyright
18681af2a9Sriastradh  *    notice, this list of conditions and the following disclaimer.
19681af2a9Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
20681af2a9Sriastradh  *    notice, this list of conditions and the following disclaimer in the
21681af2a9Sriastradh  *    documentation and/or other materials provided with the distribution.
22681af2a9Sriastradh  *
23b9d5e7eaSriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24b9d5e7eaSriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25b9d5e7eaSriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26b9d5e7eaSriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27b9d5e7eaSriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28b9d5e7eaSriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29b9d5e7eaSriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30b9d5e7eaSriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31b9d5e7eaSriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32b9d5e7eaSriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33b9d5e7eaSriastradh  * POSSIBILITY OF SUCH DAMAGE.
34681af2a9Sriastradh  */
35681af2a9Sriastradh 
36681af2a9Sriastradh #include <sys/cdefs.h>
37*e9607ed6Sthorpej __KERNEL_RCSID(0, "$NetBSD: apple_smc_acpi.c,v 1.5 2021/01/29 15:49:55 thorpej Exp $");
38681af2a9Sriastradh 
39681af2a9Sriastradh #include <sys/types.h>
40681af2a9Sriastradh #include <sys/param.h>
412a6583a2Sriastradh #include <sys/bus.h>
422a6583a2Sriastradh #include <sys/module.h>
43681af2a9Sriastradh 
44681af2a9Sriastradh #include <dev/acpi/acpireg.h>
45681af2a9Sriastradh #include <dev/acpi/acpivar.h>
46681af2a9Sriastradh 
47681af2a9Sriastradh #include <dev/ic/apple_smcreg.h>
48681af2a9Sriastradh #include <dev/ic/apple_smcvar.h>
49681af2a9Sriastradh 
50681af2a9Sriastradh #define _COMPONENT		ACPI_RESOURCE_COMPONENT
51681af2a9Sriastradh ACPI_MODULE_NAME		("apple_smc_acpi")
52681af2a9Sriastradh 
53681af2a9Sriastradh struct apple_smc_acpi_softc {
54681af2a9Sriastradh 	struct apple_smc_tag	sc_smc;
55681af2a9Sriastradh };
56681af2a9Sriastradh 
57681af2a9Sriastradh static int	apple_smc_acpi_match(device_t, cfdata_t, void *);
58681af2a9Sriastradh static void	apple_smc_acpi_attach(device_t, device_t, void *);
59681af2a9Sriastradh static int	apple_smc_acpi_detach(device_t, int);
602a6583a2Sriastradh static int	apple_smc_acpi_rescan(device_t, const char *, const int *);
612a6583a2Sriastradh static void	apple_smc_acpi_child_detached(device_t, device_t);
622a6583a2Sriastradh 
632a6583a2Sriastradh CFATTACH_DECL2_NEW(apple_smc_acpi, sizeof(struct apple_smc_acpi_softc),
642a6583a2Sriastradh     apple_smc_acpi_match,
652a6583a2Sriastradh     apple_smc_acpi_attach,
662a6583a2Sriastradh     apple_smc_acpi_detach,
672a6583a2Sriastradh     NULL /* activate */,
682a6583a2Sriastradh     apple_smc_acpi_rescan,
692a6583a2Sriastradh     apple_smc_acpi_child_detached);
70681af2a9Sriastradh 
71*e9607ed6Sthorpej static const struct device_compatible_entry compat_data[] = {
72*e9607ed6Sthorpej 	{ .compat = "APP0001" },
73*e9607ed6Sthorpej 	DEVICE_COMPAT_EOL
74681af2a9Sriastradh };
75681af2a9Sriastradh 
76681af2a9Sriastradh static int
apple_smc_acpi_match(device_t parent,cfdata_t match,void * aux)77681af2a9Sriastradh apple_smc_acpi_match(device_t parent, cfdata_t match, void *aux)
78681af2a9Sriastradh {
79681af2a9Sriastradh 	struct acpi_attach_args *aa = aux;
80681af2a9Sriastradh 
81*e9607ed6Sthorpej 	return acpi_compatible_match(aa, compat_data);
82681af2a9Sriastradh }
83681af2a9Sriastradh 
84681af2a9Sriastradh static void
apple_smc_acpi_attach(device_t parent,device_t self,void * aux)85681af2a9Sriastradh apple_smc_acpi_attach(device_t parent, device_t self, void *aux)
86681af2a9Sriastradh {
87681af2a9Sriastradh 	struct apple_smc_acpi_softc *sc = device_private(self);
88681af2a9Sriastradh 	struct apple_smc_tag *smc = &sc->sc_smc;
89681af2a9Sriastradh 	struct acpi_attach_args *aa = aux;
90681af2a9Sriastradh 	struct acpi_resources res;
91681af2a9Sriastradh 	struct acpi_io *io;
92681af2a9Sriastradh 	int rv;
93681af2a9Sriastradh 
94681af2a9Sriastradh 	smc->smc_dev = self;
95681af2a9Sriastradh 
96681af2a9Sriastradh 	aprint_normal("\n");
97681af2a9Sriastradh 	aprint_naive("\n");
98681af2a9Sriastradh 
99681af2a9Sriastradh 	rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS",
100681af2a9Sriastradh 	    &res, &acpi_resource_parse_ops_default);
101681af2a9Sriastradh 	if (ACPI_FAILURE(rv)) {
102681af2a9Sriastradh 		aprint_error_dev(self, "couldn't parse SMC resources: %s\n",
103681af2a9Sriastradh 		    AcpiFormatException(rv));
104681af2a9Sriastradh 		goto out0;
105681af2a9Sriastradh 	}
106681af2a9Sriastradh 
107681af2a9Sriastradh 	io = acpi_res_io(&res, 0);
108681af2a9Sriastradh 	if (io == NULL) {
109681af2a9Sriastradh 		aprint_error_dev(self, "no I/O resource\n");
110681af2a9Sriastradh 		goto out1;
111681af2a9Sriastradh 	}
112681af2a9Sriastradh 
113681af2a9Sriastradh 	if (io->ar_length < APPLE_SMC_REGSIZE) {
114681af2a9Sriastradh 		aprint_error_dev(self, "I/O resources too small: %"PRId32"\n",
115681af2a9Sriastradh 		    io->ar_length);
116681af2a9Sriastradh 		goto out1;
117681af2a9Sriastradh 	}
118681af2a9Sriastradh 
119681af2a9Sriastradh 	if (bus_space_map(aa->aa_iot, io->ar_base, io->ar_length, 0,
120681af2a9Sriastradh 		&smc->smc_bsh) != 0) {
121681af2a9Sriastradh 		aprint_error_dev(self, "unable to map I/O registers\n");
122681af2a9Sriastradh 		goto out1;
123681af2a9Sriastradh 	}
124681af2a9Sriastradh 
125681af2a9Sriastradh 	smc->smc_bst = aa->aa_iot;
126681af2a9Sriastradh 	smc->smc_size = io->ar_length;
127681af2a9Sriastradh 
128681af2a9Sriastradh 	apple_smc_attach(smc);
129681af2a9Sriastradh 
130681af2a9Sriastradh out1:	acpi_resource_cleanup(&res);
131681af2a9Sriastradh out0:	return;
132681af2a9Sriastradh }
133681af2a9Sriastradh 
134681af2a9Sriastradh static int
apple_smc_acpi_detach(device_t self,int flags)135681af2a9Sriastradh apple_smc_acpi_detach(device_t self, int flags)
136681af2a9Sriastradh {
137681af2a9Sriastradh 	struct apple_smc_acpi_softc *sc = device_private(self);
138681af2a9Sriastradh 	struct apple_smc_tag *smc = &sc->sc_smc;
139681af2a9Sriastradh 	int error;
140681af2a9Sriastradh 
141681af2a9Sriastradh 	if (smc->smc_size != 0) {
142681af2a9Sriastradh 		error = apple_smc_detach(smc, flags);
143681af2a9Sriastradh 		if (error)
144681af2a9Sriastradh 			return error;
145681af2a9Sriastradh 
146681af2a9Sriastradh 		bus_space_unmap(smc->smc_bst, smc->smc_bsh, smc->smc_size);
147681af2a9Sriastradh 		smc->smc_size = 0;
148681af2a9Sriastradh 	}
149681af2a9Sriastradh 
150681af2a9Sriastradh 	return 0;
151681af2a9Sriastradh }
1522a6583a2Sriastradh 
1532a6583a2Sriastradh static int
apple_smc_acpi_rescan(device_t self,const char * ifattr,const int * locs)1542a6583a2Sriastradh apple_smc_acpi_rescan(device_t self, const char *ifattr, const int *locs)
1552a6583a2Sriastradh {
1562a6583a2Sriastradh 	struct apple_smc_acpi_softc *const sc = device_private(self);
1572a6583a2Sriastradh 
1582a6583a2Sriastradh 	return apple_smc_rescan(&sc->sc_smc, ifattr, locs);
1592a6583a2Sriastradh }
1602a6583a2Sriastradh 
1612a6583a2Sriastradh static void
apple_smc_acpi_child_detached(device_t self,device_t child)1622a6583a2Sriastradh apple_smc_acpi_child_detached(device_t self, device_t child)
1632a6583a2Sriastradh {
1642a6583a2Sriastradh 	struct apple_smc_acpi_softc *const sc = device_private(self);
1652a6583a2Sriastradh 
1662a6583a2Sriastradh 	apple_smc_child_detached(&sc->sc_smc, child);
1672a6583a2Sriastradh }
1682a6583a2Sriastradh 
1692a6583a2Sriastradh MODULE(MODULE_CLASS_DRIVER, apple_smc_acpi, "apple_smc");
1702a6583a2Sriastradh 
1712a6583a2Sriastradh #ifdef _MODULE
1722a6583a2Sriastradh #include "ioconf.c"
1732a6583a2Sriastradh #endif
1742a6583a2Sriastradh 
1752a6583a2Sriastradh static int
apple_smc_acpi_modcmd(modcmd_t cmd,void * arg __unused)1762a6583a2Sriastradh apple_smc_acpi_modcmd(modcmd_t cmd, void *arg __unused)
1772a6583a2Sriastradh {
178983bdf6dSriastradh #ifdef _MODULE
1792a6583a2Sriastradh 	int error;
180983bdf6dSriastradh #endif
1812a6583a2Sriastradh 
1822a6583a2Sriastradh 	switch (cmd) {
1832a6583a2Sriastradh 	case MODULE_CMD_INIT:
1842a6583a2Sriastradh #ifdef _MODULE
1852a6583a2Sriastradh 		error = config_init_component(cfdriver_ioconf_apple_smc_acpi,
1862a6583a2Sriastradh 		    cfattach_ioconf_apple_smc_acpi,
1872a6583a2Sriastradh 		    cfdata_ioconf_apple_smc_acpi);
1882a6583a2Sriastradh 		if (error)
1892a6583a2Sriastradh 			return error;
1902a6583a2Sriastradh #endif
1912a6583a2Sriastradh 		return 0;
1922a6583a2Sriastradh 
1932a6583a2Sriastradh 	case MODULE_CMD_FINI:
1942a6583a2Sriastradh #ifdef _MODULE
1952a6583a2Sriastradh 		error = config_fini_component(cfdriver_ioconf_apple_smc_acpi,
1962a6583a2Sriastradh 		    cfattach_ioconf_apple_smc_acpi,
1972a6583a2Sriastradh 		    cfdata_ioconf_apple_smc_acpi);
1982a6583a2Sriastradh 		if (error)
1992a6583a2Sriastradh 			return error;
2002a6583a2Sriastradh #endif
2012a6583a2Sriastradh 		return 0;
2022a6583a2Sriastradh 
2032a6583a2Sriastradh 	default:
2042a6583a2Sriastradh 		return ENOTTY;
2052a6583a2Sriastradh 	}
2062a6583a2Sriastradh }
207