Tue Jan 26 00:19:53 2021 UTC ()
Add a device_t parameter to acpi_enter_i2c_devs. If non-NULL, all child
acpi_devnodes will be claimed by that device so we don't later try to
attach a duplicate device to that node at acpinodebus.


(jmcneill)
diff -r1.1 -r1.2 src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c
diff -r1.2 -r1.3 src/sys/arch/x86/pci/dwiic_pci.c
diff -r1.9 -r1.10 src/sys/dev/acpi/acpi_i2c.c
diff -r1.9 -r1.10 src/sys/dev/acpi/acpi_util.h
diff -r1.1 -r1.2 src/sys/dev/acpi/acpi_i2c.h
diff -r1.20 -r1.21 src/sys/dev/acpi/acpi_util.c
diff -r1.5 -r1.6 src/sys/dev/acpi/dwiic_acpi.c
diff -r1.2 -r1.3 src/sys/dev/acpi/nxpiic_acpi.c
diff -r1.3 -r1.4 src/sys/dev/i2c/i2cmux.c

cvs diff -r1.1 -r1.2 src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c (switch to unified diff)

--- src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c 2020/03/31 12:23:17 1.1
+++ src/sys/arch/arm/broadcom/bcm2835_bsc_acpi.c 2021/01/26 00:19:52 1.2
@@ -1,189 +1,189 @@ @@ -1,189 +1,189 @@
1/* $NetBSD: bcm2835_bsc_acpi.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $ */ 1/* $NetBSD: bcm2835_bsc_acpi.c,v 1.2 2021/01/26 00:19:52 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc_acpi.c,v 1.1 2020/03/31 12:23:17 jmcneill Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc_acpi.c,v 1.2 2021/01/26 00:19:52 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/cpu.h> 34#include <sys/cpu.h>
35#include <sys/device.h> 35#include <sys/device.h>
36 36
37#include <dev/acpi/acpireg.h> 37#include <dev/acpi/acpireg.h>
38#include <dev/acpi/acpivar.h> 38#include <dev/acpi/acpivar.h>
39#include <dev/acpi/acpi_intr.h> 39#include <dev/acpi/acpi_intr.h>
40#include <dev/acpi/acpi_i2c.h> 40#include <dev/acpi/acpi_i2c.h>
41 41
42#include <arm/broadcom/bcm2835var.h> 42#include <arm/broadcom/bcm2835var.h>
43#include <arm/broadcom/bcm2835_mbox.h> 43#include <arm/broadcom/bcm2835_mbox.h>
44#include <arm/broadcom/bcm2835_bscvar.h> 44#include <arm/broadcom/bcm2835_bscvar.h>
45 45
46#include <evbarm/rpi/vcio.h> 46#include <evbarm/rpi/vcio.h>
47#include <evbarm/rpi/vcpm.h> 47#include <evbarm/rpi/vcpm.h>
48#include <evbarm/rpi/vcprop.h> 48#include <evbarm/rpi/vcprop.h>
49 49
50static int bsciic_acpi_match(device_t, cfdata_t, void *); 50static int bsciic_acpi_match(device_t, cfdata_t, void *);
51static void bsciic_acpi_attach(device_t, device_t, void *); 51static void bsciic_acpi_attach(device_t, device_t, void *);
52 52
53static u_int bsciic_acpi_vpu_clock_rate(void); 53static u_int bsciic_acpi_vpu_clock_rate(void);
54 54
55CFATTACH_DECL_NEW(bsciic_acpi, sizeof(struct bsciic_softc), bsciic_acpi_match, bsciic_acpi_attach, NULL, NULL); 55CFATTACH_DECL_NEW(bsciic_acpi, sizeof(struct bsciic_softc), bsciic_acpi_match, bsciic_acpi_attach, NULL, NULL);
56 56
57static const char * const compatible[] = { 57static const char * const compatible[] = {
58 "BCM2841", 58 "BCM2841",
59 NULL 59 NULL
60}; 60};
61 61
62static struct { 62static struct {
63 struct vcprop_buffer_hdr vb_hdr; 63 struct vcprop_buffer_hdr vb_hdr;
64 struct vcprop_tag_clockrate vbt_vpuclockrate; 64 struct vcprop_tag_clockrate vbt_vpuclockrate;
65 struct vcprop_tag end; 65 struct vcprop_tag end;
66} vb_vpu __cacheline_aligned = { 66} vb_vpu __cacheline_aligned = {
67 .vb_hdr = { 67 .vb_hdr = {
68 .vpb_len = sizeof(vb_vpu), 68 .vpb_len = sizeof(vb_vpu),
69 .vpb_rcode = VCPROP_PROCESS_REQUEST 69 .vpb_rcode = VCPROP_PROCESS_REQUEST
70 }, 70 },
71 .vbt_vpuclockrate = { 71 .vbt_vpuclockrate = {
72 .tag = { 72 .tag = {
73 .vpt_tag = VCPROPTAG_GET_CLOCKRATE, 73 .vpt_tag = VCPROPTAG_GET_CLOCKRATE,
74 .vpt_len = VCPROPTAG_LEN(vb_vpu.vbt_vpuclockrate), 74 .vpt_len = VCPROPTAG_LEN(vb_vpu.vbt_vpuclockrate),
75 .vpt_rcode = VCPROPTAG_REQUEST 75 .vpt_rcode = VCPROPTAG_REQUEST
76 }, 76 },
77 .id = VCPROP_CLK_CORE 77 .id = VCPROP_CLK_CORE
78 }, 78 },
79 .end = { 79 .end = {
80 .vpt_tag = VCPROPTAG_NULL 80 .vpt_tag = VCPROPTAG_NULL
81 } 81 }
82}; 82};
83 83
84static int 84static int
85bsciic_acpi_match(device_t parent, cfdata_t cf, void *aux) 85bsciic_acpi_match(device_t parent, cfdata_t cf, void *aux)
86{ 86{
87 struct acpi_attach_args *aa = aux; 87 struct acpi_attach_args *aa = aux;
88 88
89 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) 89 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
90 return 0; 90 return 0;
91 91
92 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible); 92 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
93} 93}
94 94
95static void 95static void
96bsciic_acpi_attach(device_t parent, device_t self, void *aux) 96bsciic_acpi_attach(device_t parent, device_t self, void *aux)
97{ 97{
98 struct bsciic_softc * const sc = device_private(self); 98 struct bsciic_softc * const sc = device_private(self);
99 struct acpi_attach_args *aa = aux; 99 struct acpi_attach_args *aa = aux;
100 struct i2cbus_attach_args iba; 100 struct i2cbus_attach_args iba;
101 struct acpi_resources res; 101 struct acpi_resources res;
102 struct acpi_mem *mem; 102 struct acpi_mem *mem;
103 struct acpi_irq *irq; 103 struct acpi_irq *irq;
104 ACPI_STATUS rv; 104 ACPI_STATUS rv;
105 ACPI_INTEGER clock_freq; 105 ACPI_INTEGER clock_freq;
106 void *ih; 106 void *ih;
107 107
108 sc->sc_dev = self; 108 sc->sc_dev = self;
109 109
110 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS", 110 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS",
111 &res, &acpi_resource_parse_ops_default); 111 &res, &acpi_resource_parse_ops_default);
112 if (ACPI_FAILURE(rv)) 112 if (ACPI_FAILURE(rv))
113 return; 113 return;
114 114
115 mem = acpi_res_mem(&res, 0); 115 mem = acpi_res_mem(&res, 0);
116 if (mem == NULL) { 116 if (mem == NULL) {
117 aprint_error_dev(self, "couldn't find mem resource\n"); 117 aprint_error_dev(self, "couldn't find mem resource\n");
118 goto done; 118 goto done;
119 } 119 }
120 120
121 irq = acpi_res_irq(&res, 0); 121 irq = acpi_res_irq(&res, 0);
122 if (irq == NULL) { 122 if (irq == NULL) {
123 aprint_error_dev(self, "couldn't find irq resource\n"); 123 aprint_error_dev(self, "couldn't find irq resource\n");
124 goto done; 124 goto done;
125 } 125 }
126 126
127 sc->sc_dev = self; 127 sc->sc_dev = self;
128 sc->sc_iot = aa->aa_memt; 128 sc->sc_iot = aa->aa_memt;
129 if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0, &sc->sc_ioh) != 0) { 129 if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0, &sc->sc_ioh) != 0) {
130 aprint_error_dev(self, "couldn't map registers\n"); 130 aprint_error_dev(self, "couldn't map registers\n");
131 goto done; 131 goto done;
132 } 132 }
133 133
134 sc->sc_frequency = bsciic_acpi_vpu_clock_rate(); 134 sc->sc_frequency = bsciic_acpi_vpu_clock_rate();
135 if (sc->sc_frequency == 0) { 135 if (sc->sc_frequency == 0) {
136 aprint_error_dev(self, "couldn't determine parent clock rate\n"); 136 aprint_error_dev(self, "couldn't determine parent clock rate\n");
137 goto done; 137 goto done;
138 } 138 }
139 139
140 rv = acpi_dsd_integer(aa->aa_node->ad_handle, "clock-frequency", &clock_freq); 140 rv = acpi_dsd_integer(aa->aa_node->ad_handle, "clock-frequency", &clock_freq);
141 if (ACPI_SUCCESS(rv)) 141 if (ACPI_SUCCESS(rv))
142 sc->sc_clkrate = clock_freq; 142 sc->sc_clkrate = clock_freq;
143 else 143 else
144 sc->sc_clkrate = 100000; 144 sc->sc_clkrate = 100000;
145 145
146 bsciic_attach(sc); 146 bsciic_attach(sc);
147 147
148 ih = acpi_intr_establish(self, (uint64_t)aa->aa_node->ad_handle, 148 ih = acpi_intr_establish(self, (uint64_t)aa->aa_node->ad_handle,
149 IPL_VM, true, bsciic_intr, sc, device_xname(self)); 149 IPL_VM, true, bsciic_intr, sc, device_xname(self));
150 if (ih == NULL) { 150 if (ih == NULL) {
151 aprint_error_dev(self, "couldn't install interrupt handler\n"); 151 aprint_error_dev(self, "couldn't install interrupt handler\n");
152 goto done; 152 goto done;
153 } 153 }
154 154
155 iic_tag_init(&sc->sc_i2c); 155 iic_tag_init(&sc->sc_i2c);
156 sc->sc_i2c.ic_cookie = sc; 156 sc->sc_i2c.ic_cookie = sc;
157 sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus; 157 sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus;
158 sc->sc_i2c.ic_release_bus = bsciic_release_bus; 158 sc->sc_i2c.ic_release_bus = bsciic_release_bus;
159 sc->sc_i2c.ic_exec = bsciic_exec; 159 sc->sc_i2c.ic_exec = bsciic_exec;
160 160
161 memset(&iba, 0, sizeof(iba)); 161 memset(&iba, 0, sizeof(iba));
162 iba.iba_tag = &sc->sc_i2c; 162 iba.iba_tag = &sc->sc_i2c;
163 iba.iba_child_devices = acpi_enter_i2c_devs(aa->aa_node); 163 iba.iba_child_devices = acpi_enter_i2c_devs(self, aa->aa_node);
164 config_found_ia(self, "i2cbus", &iba, iicbus_print); 164 config_found_ia(self, "i2cbus", &iba, iicbus_print);
165 165
166done: 166done:
167 acpi_resource_cleanup(&res); 167 acpi_resource_cleanup(&res);
168} 168}
169 169
170static u_int 170static u_int
171bsciic_acpi_vpu_clock_rate(void) 171bsciic_acpi_vpu_clock_rate(void)
172{ 172{
173 uint32_t res; 173 uint32_t res;
174 int error; 174 int error;
175 175
176 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_vpu, 176 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_vpu,
177 sizeof(vb_vpu), &res); 177 sizeof(vb_vpu), &res);
178 if (error != 0) { 178 if (error != 0) {
179 printf("%s: mbox request failed (%d)\n", __func__, error); 179 printf("%s: mbox request failed (%d)\n", __func__, error);
180 return 0; 180 return 0;
181 } 181 }
182 182
183 if (!vcprop_buffer_success_p(&vb_vpu.vb_hdr) || 183 if (!vcprop_buffer_success_p(&vb_vpu.vb_hdr) ||
184 !vcprop_tag_success_p(&vb_vpu.vbt_vpuclockrate.tag) || 184 !vcprop_tag_success_p(&vb_vpu.vbt_vpuclockrate.tag) ||
185 vb_vpu.vbt_vpuclockrate.rate < 0) 185 vb_vpu.vbt_vpuclockrate.rate < 0)
186 return 0; 186 return 0;
187 187
188 return vb_vpu.vbt_vpuclockrate.rate; 188 return vb_vpu.vbt_vpuclockrate.rate;
189} 189}

cvs diff -r1.2 -r1.3 src/sys/arch/x86/pci/dwiic_pci.c (switch to unified diff)

--- src/sys/arch/x86/pci/dwiic_pci.c 2018/09/26 19:06:33 1.2
+++ src/sys/arch/x86/pci/dwiic_pci.c 2021/01/26 00:19:52 1.3
@@ -1,215 +1,215 @@ @@ -1,215 +1,215 @@
1/* $NetBSD: dwiic_pci.c,v 1.2 2018/09/26 19:06:33 jakllsch Exp $ */ 1/* $NetBSD: dwiic_pci.c,v 1.3 2021/01/26 00:19:52 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Manuel Bouyer. 8 * by Manuel Bouyer.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31/* 31/*
32 * Synopsys DesignWare I2C controller, PCI front-end 32 * Synopsys DesignWare I2C controller, PCI front-end
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: dwiic_pci.c,v 1.2 2018/09/26 19:06:33 jakllsch Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: dwiic_pci.c,v 1.3 2021/01/26 00:19:52 jmcneill Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40 40
41#include <dev/pci/pcireg.h> 41#include <dev/pci/pcireg.h>
42#include <dev/pci/pcivar.h> 42#include <dev/pci/pcivar.h>
43#include <dev/pci/pcidevs.h> 43#include <dev/pci/pcidevs.h>
44 44
45#include <dev/acpi/acpivar.h> 45#include <dev/acpi/acpivar.h>
46#include <dev/acpi/acpi_pci.h> 46#include <dev/acpi/acpi_pci.h>
47#include <dev/acpi/acpi_util.h> 47#include <dev/acpi/acpi_util.h>
48#include <dev/acpi/acpi_i2c.h> 48#include <dev/acpi/acpi_i2c.h>
49 49
50#include <dev/ic/dwiic_var.h> 50#include <dev/ic/dwiic_var.h>
51#include <arch/x86/pci/lpssreg.h> 51#include <arch/x86/pci/lpssreg.h>
52 52
53//#define DWIIC_DEBUG 53//#define DWIIC_DEBUG
54 54
55#ifdef DWIIC_DEBUG 55#ifdef DWIIC_DEBUG
56#define DPRINTF(x) printf x 56#define DPRINTF(x) printf x
57#else 57#else
58#define DPRINTF(x) 58#define DPRINTF(x)
59#endif 59#endif
60 60
61struct pci_dwiic_softc { 61struct pci_dwiic_softc {
62 struct dwiic_softc sc_dwiic; 62 struct dwiic_softc sc_dwiic;
63 pci_chipset_tag_t sc_pc; 63 pci_chipset_tag_t sc_pc;
64 pcitag_t sc_ptag; 64 pcitag_t sc_ptag;
65 struct acpi_devnode *sc_acpinode; 65 struct acpi_devnode *sc_acpinode;
66}; 66};
67 67
68static uint32_t 68static uint32_t
69lpss_read(struct pci_dwiic_softc *sc, int offset) 69lpss_read(struct pci_dwiic_softc *sc, int offset)
70{ 70{
71 u_int32_t b = bus_space_read_4(sc->sc_dwiic.sc_iot, sc->sc_dwiic.sc_ioh, 71 u_int32_t b = bus_space_read_4(sc->sc_dwiic.sc_iot, sc->sc_dwiic.sc_ioh,
72 offset); 72 offset);
73 return b; 73 return b;
74} 74}
75 75
76static void 76static void
77lpss_write(struct pci_dwiic_softc *sc, int offset, uint32_t val) 77lpss_write(struct pci_dwiic_softc *sc, int offset, uint32_t val)
78{ 78{
79 bus_space_write_4(sc->sc_dwiic.sc_iot, sc->sc_dwiic.sc_ioh, 79 bus_space_write_4(sc->sc_dwiic.sc_iot, sc->sc_dwiic.sc_ioh,
80 offset, val); 80 offset, val);
81} 81}
82 82
83static int pci_dwiic_match(device_t, cfdata_t, void *); 83static int pci_dwiic_match(device_t, cfdata_t, void *);
84static void pci_dwiic_attach(device_t, device_t, void *); 84static void pci_dwiic_attach(device_t, device_t, void *);
85static bool dwiic_pci_power(struct dwiic_softc *, bool); 85static bool dwiic_pci_power(struct dwiic_softc *, bool);
86 86
87CFATTACH_DECL_NEW(pcidwiic, sizeof(struct pci_dwiic_softc), 87CFATTACH_DECL_NEW(pcidwiic, sizeof(struct pci_dwiic_softc),
88 pci_dwiic_match, pci_dwiic_attach, dwiic_detach, NULL); 88 pci_dwiic_match, pci_dwiic_attach, dwiic_detach, NULL);
89 89
90 90
91int 91int
92pci_dwiic_match(device_t parent, cfdata_t match, void *aux) 92pci_dwiic_match(device_t parent, cfdata_t match, void *aux)
93{ 93{
94 struct pci_attach_args *pa = aux; 94 struct pci_attach_args *pa = aux;
95 95
96 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) 96 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
97 return 0; 97 return 0;
98 98
99 if (PCI_PRODUCT(pa->pa_id) < PCI_PRODUCT_INTEL_100SERIES_LP_I2C_0 || 99 if (PCI_PRODUCT(pa->pa_id) < PCI_PRODUCT_INTEL_100SERIES_LP_I2C_0 ||
100 PCI_PRODUCT(pa->pa_id) > PCI_PRODUCT_INTEL_100SERIES_LP_I2C_3) 100 PCI_PRODUCT(pa->pa_id) > PCI_PRODUCT_INTEL_100SERIES_LP_I2C_3)
101 return 0; 101 return 0;
102 102
103 return 1; 103 return 1;
104} 104}
105 105
106void 106void
107pci_dwiic_attach(device_t parent, device_t self, void *aux) 107pci_dwiic_attach(device_t parent, device_t self, void *aux)
108{ 108{
109 struct pci_dwiic_softc *sc = device_private(self); 109 struct pci_dwiic_softc *sc = device_private(self);
110 struct pci_attach_args *pa = aux; 110 struct pci_attach_args *pa = aux;
111 const char *intrstr; 111 const char *intrstr;
112 pci_intr_handle_t intrhandle; 112 pci_intr_handle_t intrhandle;
113 char intrbuf[PCI_INTRSTR_LEN]; 113 char intrbuf[PCI_INTRSTR_LEN];
114 pcireg_t memtype; 114 pcireg_t memtype;
115 pcireg_t csr; 115 pcireg_t csr;
116 uint32_t caps; 116 uint32_t caps;
117 117
118 sc->sc_dwiic.sc_dev = self; 118 sc->sc_dwiic.sc_dev = self;
119 sc->sc_dwiic.sc_power = dwiic_pci_power; 119 sc->sc_dwiic.sc_power = dwiic_pci_power;
120 sc->sc_dwiic.sc_type = dwiic_type_sunrisepoint; 120 sc->sc_dwiic.sc_type = dwiic_type_sunrisepoint;
121 121
122 sc->sc_pc = pa->pa_pc; 122 sc->sc_pc = pa->pa_pc;
123 sc->sc_ptag = pa->pa_tag; 123 sc->sc_ptag = pa->pa_tag;
124 124
125 /* register access not enabled by BIOS */ 125 /* register access not enabled by BIOS */
126 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 126 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
127 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 127 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
128 csr | PCI_COMMAND_MEM_ENABLE); 128 csr | PCI_COMMAND_MEM_ENABLE);
129 129
130 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR0); 130 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR0);
131 if (pci_mapreg_map(pa, PCI_BAR0, memtype, 0, &sc->sc_dwiic.sc_iot, 131 if (pci_mapreg_map(pa, PCI_BAR0, memtype, 0, &sc->sc_dwiic.sc_iot,
132 &sc->sc_dwiic.sc_ioh, NULL, NULL) != 0) { 132 &sc->sc_dwiic.sc_ioh, NULL, NULL) != 0) {
133 aprint_error(": can't map register space\n"); 133 aprint_error(": can't map register space\n");
134 goto out; 134 goto out;
135 } 135 }
136 dwiic_pci_power(&sc->sc_dwiic, 1); 136 dwiic_pci_power(&sc->sc_dwiic, 1);
137 137
138 caps = lpss_read(sc, LPSS_CAP); 138 caps = lpss_read(sc, LPSS_CAP);
139 139
140 aprint_naive(": I2C controller\n"); 140 aprint_naive(": I2C controller\n");
141 aprint_normal(": I2C controller instance %d\n", 141 aprint_normal(": I2C controller instance %d\n",
142 (int)(caps & LPSS_CAP_INSTANCE)); 142 (int)(caps & LPSS_CAP_INSTANCE));
143 143
144 if (pci_intr_map(pa, &intrhandle)) { 144 if (pci_intr_map(pa, &intrhandle)) {
145 aprint_error_dev(self, "can't map interrupt\n"); 145 aprint_error_dev(self, "can't map interrupt\n");
146 goto out; 146 goto out;
147 } 147 }
148 intrstr = pci_intr_string(pa->pa_pc, intrhandle, 148 intrstr = pci_intr_string(pa->pa_pc, intrhandle,
149 intrbuf, sizeof(intrbuf)); 149 intrbuf, sizeof(intrbuf));
150 150
151 sc->sc_dwiic.sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, 151 sc->sc_dwiic.sc_ih = pci_intr_establish(pa->pa_pc, intrhandle,
152 IPL_VM, dwiic_intr, sc); 152 IPL_VM, dwiic_intr, sc);
153 if (sc->sc_dwiic.sc_ih == NULL) { 153 if (sc->sc_dwiic.sc_ih == NULL) {
154 aprint_error_dev(self, "couldn't establish interrupt"); 154 aprint_error_dev(self, "couldn't establish interrupt");
155 if (intrstr != NULL) 155 if (intrstr != NULL)
156 aprint_error(" at %s", intrstr); 156 aprint_error(" at %s", intrstr);
157 aprint_error("\n"); 157 aprint_error("\n");
158 goto out; 158 goto out;
159 } 159 }
160 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 160 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
161 161
162 lpss_write(sc, LPSS_RESET, LPSS_RESET_CTRL_REL); 162 lpss_write(sc, LPSS_RESET, LPSS_RESET_CTRL_REL);
163 lpss_write(sc, LPSS_REMAP_LO, 163 lpss_write(sc, LPSS_REMAP_LO,
164 pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_BAR0)); 164 pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_BAR0));
165 lpss_write(sc, LPSS_REMAP_HI, 165 lpss_write(sc, LPSS_REMAP_HI,
166 pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_BAR0 + 0x4)); 166 pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_BAR0 + 0x4));
167 167
168 sc->sc_acpinode = acpi_pcidev_find(0 /*XXX segment*/, 168 sc->sc_acpinode = acpi_pcidev_find(0 /*XXX segment*/,
169 pa->pa_bus, pa->pa_device, pa->pa_function); 169 pa->pa_bus, pa->pa_device, pa->pa_function);
170 170
171 if (sc->sc_acpinode) { 171 if (sc->sc_acpinode) {
172 sc->sc_dwiic.sc_iba.iba_child_devices =  172 sc->sc_dwiic.sc_iba.iba_child_devices =
173 acpi_enter_i2c_devs(sc->sc_acpinode); 173 acpi_enter_i2c_devs(NULL, sc->sc_acpinode);
174 } else { 174 } else {
175 aprint_verbose_dev(self, "no matching ACPI node\n"); 175 aprint_verbose_dev(self, "no matching ACPI node\n");
176 } 176 }
177 177
178 dwiic_attach(&sc->sc_dwiic); 178 dwiic_attach(&sc->sc_dwiic);
179 179
180 config_found_ia(self, "i2cbus", &sc->sc_dwiic.sc_iba, iicbus_print); 180 config_found_ia(self, "i2cbus", &sc->sc_dwiic.sc_iba, iicbus_print);
181 181
182 pmf_device_register(self, dwiic_suspend, dwiic_resume); 182 pmf_device_register(self, dwiic_suspend, dwiic_resume);
183 183
184out: 184out:
185 return; 185 return;
186} 186}
187 187
188static bool 188static bool
189dwiic_pci_power(struct dwiic_softc *dwsc, bool power) 189dwiic_pci_power(struct dwiic_softc *dwsc, bool power)
190{ 190{
191 struct pci_dwiic_softc *sc = (void *)dwsc; 191 struct pci_dwiic_softc *sc = (void *)dwsc;
192 pcireg_t pmreg; 192 pcireg_t pmreg;
193 193
194 printf("status 0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_COMMAND_STATUS_REG)); 194 printf("status 0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_ptag, PCI_COMMAND_STATUS_REG));
195 printf("reset 0x%x\n", lpss_read(sc, LPSS_RESET)); 195 printf("reset 0x%x\n", lpss_read(sc, LPSS_RESET));
196 printf("rlo 0x%x\n", lpss_read(sc, LPSS_REMAP_LO)); 196 printf("rlo 0x%x\n", lpss_read(sc, LPSS_REMAP_LO));
197 printf("rho 0x%x\n", lpss_read(sc, LPSS_REMAP_HI)); 197 printf("rho 0x%x\n", lpss_read(sc, LPSS_REMAP_HI));
198 198
199 if (!power) 199 if (!power)
200 lpss_write(sc, LPSS_CLKGATE, LPSS_CLKGATE_CTRL_OFF); 200 lpss_write(sc, LPSS_CLKGATE, LPSS_CLKGATE_CTRL_OFF);
201 if (pci_get_capability(sc->sc_pc, sc->sc_ptag, PCI_CAP_PWRMGMT, 201 if (pci_get_capability(sc->sc_pc, sc->sc_ptag, PCI_CAP_PWRMGMT,
202 &pmreg, NULL)) { 202 &pmreg, NULL)) {
203 DPRINTF(("%s: power status 0x%x", device_xname(dwsc->sc_dev), 203 DPRINTF(("%s: power status 0x%x", device_xname(dwsc->sc_dev),
204 pci_conf_read(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR))); 204 pci_conf_read(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR)));
205 pci_conf_write(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR, 205 pci_conf_write(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR,
206 power ? PCI_PMCSR_STATE_D0 : PCI_PMCSR_STATE_D3); 206 power ? PCI_PMCSR_STATE_D0 : PCI_PMCSR_STATE_D3);
207 DELAY(10000); /* 10 milliseconds */ 207 DELAY(10000); /* 10 milliseconds */
208 DPRINTF((" -> 0x%x\n",  208 DPRINTF((" -> 0x%x\n",
209 pci_conf_read(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR))); 209 pci_conf_read(sc->sc_pc, sc->sc_ptag, pmreg + PCI_PMCSR)));
210 } 210 }
211 if (power) { 211 if (power) {
212 lpss_write(sc, LPSS_CLKGATE, LPSS_CLKGATE_CTRL_ON); 212 lpss_write(sc, LPSS_CLKGATE, LPSS_CLKGATE_CTRL_ON);
213 } 213 }
214 return true; 214 return true;
215} 215}

cvs diff -r1.9 -r1.10 src/sys/dev/acpi/acpi_i2c.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_i2c.c 2021/01/25 12:15:32 1.9
+++ src/sys/dev/acpi/acpi_i2c.c 2021/01/26 00:19:53 1.10
@@ -1,244 +1,249 @@ @@ -1,244 +1,249 @@
1/* $NetBSD: acpi_i2c.c,v 1.9 2021/01/25 12:15:32 jmcneill Exp $ */ 1/* $NetBSD: acpi_i2c.c,v 1.10 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Manuel Bouyer. 8 * by Manuel Bouyer.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: acpi_i2c.c,v 1.9 2021/01/25 12:15:32 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: acpi_i2c.c,v 1.10 2021/01/26 00:19:53 jmcneill Exp $");
34 34
35#include <dev/acpi/acpireg.h> 35#include <dev/acpi/acpireg.h>
36#include <dev/acpi/acpivar.h> 36#include <dev/acpi/acpivar.h>
37#include <dev/acpi/acpi_i2c.h> 37#include <dev/acpi/acpi_i2c.h>
38#include <dev/i2c/i2cvar.h> 38#include <dev/i2c/i2cvar.h>
39 39
40#define _COMPONENT ACPI_BUS_COMPONENT 40#define _COMPONENT ACPI_BUS_COMPONENT
41ACPI_MODULE_NAME ("acpi_i2c") 41ACPI_MODULE_NAME ("acpi_i2c")
42 42
43static void 43static void
44acpi_enter_i2c_hid(struct acpi_devnode *devnode, prop_dictionary_t dev) 44acpi_enter_i2c_hid(struct acpi_devnode *devnode, prop_dictionary_t dev)
45{ 45{
46 ACPI_OBJECT_LIST arg; 46 ACPI_OBJECT_LIST arg;
47 ACPI_OBJECT obj[4]; 47 ACPI_OBJECT obj[4];
48 ACPI_OBJECT *osc; 48 ACPI_OBJECT *osc;
49 ACPI_BUFFER buf; 49 ACPI_BUFFER buf;
50 ACPI_STATUS rv; 50 ACPI_STATUS rv;
51 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */ 51 /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
52 static uint8_t i2c_hid_guid[] = { 52 static uint8_t i2c_hid_guid[] = {
53 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45, 53 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
54 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, 54 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
55 }; 55 };
56 56
57 arg.Count = 4; 57 arg.Count = 4;
58 arg.Pointer = obj; 58 arg.Pointer = obj;
59 59
60 obj[0].Type = ACPI_TYPE_BUFFER; 60 obj[0].Type = ACPI_TYPE_BUFFER;
61 obj[0].Buffer.Length = sizeof(i2c_hid_guid); 61 obj[0].Buffer.Length = sizeof(i2c_hid_guid);
62 obj[0].Buffer.Pointer = i2c_hid_guid; 62 obj[0].Buffer.Pointer = i2c_hid_guid;
63 63
64 /* rev */ 64 /* rev */
65 obj[1].Type = ACPI_TYPE_INTEGER; 65 obj[1].Type = ACPI_TYPE_INTEGER;
66 obj[1].Integer.Value = 1; 66 obj[1].Integer.Value = 1;
67 67
68 /* func */ 68 /* func */
69 obj[2].Type = ACPI_TYPE_INTEGER; 69 obj[2].Type = ACPI_TYPE_INTEGER;
70 obj[2].Integer.Value = 1; 70 obj[2].Integer.Value = 1;
71 71
72 obj[3].Type = ACPI_TYPE_PACKAGE; 72 obj[3].Type = ACPI_TYPE_PACKAGE;
73 obj[3].Buffer.Length = 0; 73 obj[3].Buffer.Length = 0;
74 74
75 buf.Pointer = NULL; 75 buf.Pointer = NULL;
76 buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 76 buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
77 77
78 rv = AcpiEvaluateObject(devnode->ad_handle, "_DSM", &arg, &buf); 78 rv = AcpiEvaluateObject(devnode->ad_handle, "_DSM", &arg, &buf);
79 79
80 if (ACPI_FAILURE(rv)) { 80 if (ACPI_FAILURE(rv)) {
81 aprint_error("failed to evaluate _DSM for %s: %s\n", 81 aprint_error("failed to evaluate _DSM for %s: %s\n",
82 devnode->ad_name, AcpiFormatException(rv)); 82 devnode->ad_name, AcpiFormatException(rv));
83 return; 83 return;
84 } 84 }
85 85
86 osc = buf.Pointer; 86 osc = buf.Pointer;
87 if (osc->Type != ACPI_TYPE_INTEGER) { 87 if (osc->Type != ACPI_TYPE_INTEGER) {
88 aprint_error("bad _DSM return type %d for %s\n", 88 aprint_error("bad _DSM return type %d for %s\n",
89 osc->Type, devnode->ad_name); 89 osc->Type, devnode->ad_name);
90 return; 90 return;
91 } 91 }
92 prop_dictionary_set_uint32(dev, "hid-descr-addr", osc->Integer.Value); 92 prop_dictionary_set_uint32(dev, "hid-descr-addr", osc->Integer.Value);
93} 93}
94 94
95struct acpi_i2c_id { 95struct acpi_i2c_id {
96 const char *id; 96 const char *id;
97 const char *compat; 97 const char *compat;
98 const int compatlen; 98 const int compatlen;
99 void (*parse)(struct acpi_devnode *, prop_dictionary_t); 99 void (*parse)(struct acpi_devnode *, prop_dictionary_t);
100}; 100};
101 101
102static const struct acpi_i2c_id acpi_i2c_ids[] = { 102static const struct acpi_i2c_id acpi_i2c_ids[] = {
103 { 103 {
104 .id = "PNP0C50", 104 .id = "PNP0C50",
105 .compat = "hid-over-i2c", 105 .compat = "hid-over-i2c",
106 .compatlen = 13, 106 .compatlen = 13,
107 .parse = acpi_enter_i2c_hid 107 .parse = acpi_enter_i2c_hid
108 }, 108 },
109 { 109 {
110 .id = "ACPI0C50", 110 .id = "ACPI0C50",
111 .compat = "hid-over-i2c", 111 .compat = "hid-over-i2c",
112 .compatlen = 13, 112 .compatlen = 13,
113 .parse = acpi_enter_i2c_hid 113 .parse = acpi_enter_i2c_hid
114 }, 114 },
115 { 115 {
116 .id = "NXP0002", 116 .id = "NXP0002",
117 .compat = "nxp,pca9547", 117 .compat = "nxp,pca9547",
118 .compatlen = 12, 118 .compatlen = 12,
119 .parse = NULL 119 .parse = NULL
120 }, 120 },
121 { 121 {
122 .id = NULL, 122 .id = NULL,
123 .compat = NULL, 123 .compat = NULL,
124 .compatlen = 0, 124 .compatlen = 0,
125 .parse = NULL 125 .parse = NULL
126 } 126 }
127}; 127};
128 128
129static const struct acpi_i2c_id * 129static const struct acpi_i2c_id *
130acpi_i2c_search(const char *name) 130acpi_i2c_search(const char *name)
131{ 131{
132 int i; 132 int i;
133 for (i = 0; acpi_i2c_ids[i].id != NULL; i++) { 133 for (i = 0; acpi_i2c_ids[i].id != NULL; i++) {
134 if (strcmp(name, acpi_i2c_ids[i].id) == 0) 134 if (strcmp(name, acpi_i2c_ids[i].id) == 0)
135 return &acpi_i2c_ids[i]; 135 return &acpi_i2c_ids[i];
136 } 136 }
137 return NULL; 137 return NULL;
138} 138}
139 139
140struct acpi_i2c_context { 140struct acpi_i2c_context {
141 uint16_t i2c_addr; 141 uint16_t i2c_addr;
142}; 142};
143 143
144static ACPI_STATUS 144static ACPI_STATUS
145acpi_i2c_resource_parse_callback(ACPI_RESOURCE *res, void *context) 145acpi_i2c_resource_parse_callback(ACPI_RESOURCE *res, void *context)
146{ 146{
147 struct acpi_i2c_context *i2cc = context; 147 struct acpi_i2c_context *i2cc = context;
148 148
149 switch (res->Type) { 149 switch (res->Type) {
150 case ACPI_RESOURCE_TYPE_END_TAG: 150 case ACPI_RESOURCE_TYPE_END_TAG:
151 break; 151 break;
152 case ACPI_RESOURCE_TYPE_SERIAL_BUS: 152 case ACPI_RESOURCE_TYPE_SERIAL_BUS:
153 switch (res->Data.I2cSerialBus.Type) { 153 switch (res->Data.I2cSerialBus.Type) {
154 case ACPI_RESOURCE_SERIAL_TYPE_I2C: 154 case ACPI_RESOURCE_SERIAL_TYPE_I2C:
155 i2cc->i2c_addr = res->Data.I2cSerialBus.SlaveAddress; 155 i2cc->i2c_addr = res->Data.I2cSerialBus.SlaveAddress;
156 break; 156 break;
157 } 157 }
158 break; 158 break;
159 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 159 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
160 break; 160 break;
161 default: 161 default:
162 printf("resource type 0x%x ignored\n", res->Type); 162 printf("resource type 0x%x ignored\n", res->Type);
163 } 163 }
164 return_ACPI_STATUS(AE_OK); 164 return_ACPI_STATUS(AE_OK);
165} 165}
166 166
167static void 167static void
168acpi_enter_i2c_device(struct acpi_devnode *ad, prop_array_t array) 168acpi_enter_i2c_device(struct acpi_devnode *ad, prop_array_t array)
169{ 169{
170 prop_dictionary_t dev; 170 prop_dictionary_t dev;
171 struct acpi_i2c_context i2cc; 171 struct acpi_i2c_context i2cc;
172 ACPI_STATUS rv; 172 ACPI_STATUS rv;
173 int cidi; 173 int cidi;
174 ACPI_PNP_DEVICE_ID_LIST *idlist; 174 ACPI_PNP_DEVICE_ID_LIST *idlist;
175 const char *name; 175 const char *name;
176 static const struct acpi_i2c_id *i2c_id; 176 static const struct acpi_i2c_id *i2c_id;
177 177
178 memset(&i2cc, 0, sizeof(i2cc)); 178 memset(&i2cc, 0, sizeof(i2cc));
179 rv = AcpiWalkResources(ad->ad_handle, "_CRS", 179 rv = AcpiWalkResources(ad->ad_handle, "_CRS",
180 acpi_i2c_resource_parse_callback, &i2cc); 180 acpi_i2c_resource_parse_callback, &i2cc);
181 if (ACPI_FAILURE(rv)) { 181 if (ACPI_FAILURE(rv)) {
182 aprint_error("ACPI: unable to get resources " 182 aprint_error("ACPI: unable to get resources "
183 "for %s: %s\n", ad->ad_name, 183 "for %s: %s\n", ad->ad_name,
184 AcpiFormatException(rv)); 184 AcpiFormatException(rv));
185 return; 185 return;
186 } 186 }
187 if (i2cc.i2c_addr == 0) 187 if (i2cc.i2c_addr == 0)
188 return; 188 return;
189 dev = prop_dictionary_create(); 189 dev = prop_dictionary_create();
190 if (dev == NULL) { 190 if (dev == NULL) {
191 aprint_error("ignoring device %s (no memory)\n", 191 aprint_error("ignoring device %s (no memory)\n",
192 ad->ad_name); 192 ad->ad_name);
193 return; 193 return;
194 } 194 }
195 if ((ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0) 195 if ((ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
196 name = ad->ad_name; 196 name = ad->ad_name;
197 else 197 else
198 name = ad->ad_devinfo->HardwareId.String; 198 name = ad->ad_devinfo->HardwareId.String;
199 prop_dictionary_set_string(dev, "name", name); 199 prop_dictionary_set_string(dev, "name", name);
200 prop_dictionary_set_uint32(dev, "addr", i2cc.i2c_addr); 200 prop_dictionary_set_uint32(dev, "addr", i2cc.i2c_addr);
201 prop_dictionary_set_uint64(dev, "cookie", (uintptr_t)ad->ad_handle); 201 prop_dictionary_set_uint64(dev, "cookie", (uintptr_t)ad->ad_handle);
202 prop_dictionary_set_uint32(dev, "cookietype", I2C_COOKIE_ACPI); 202 prop_dictionary_set_uint32(dev, "cookietype", I2C_COOKIE_ACPI);
203 /* first search by name, then by CID */ 203 /* first search by name, then by CID */
204 i2c_id = acpi_i2c_search(name); 204 i2c_id = acpi_i2c_search(name);
205 idlist = &ad->ad_devinfo->CompatibleIdList; 205 idlist = &ad->ad_devinfo->CompatibleIdList;
206 for (cidi = 0; 206 for (cidi = 0;
207 cidi < idlist->Count && i2c_id == NULL; 207 cidi < idlist->Count && i2c_id == NULL;
208 cidi++) { 208 cidi++) {
209 i2c_id = acpi_i2c_search(idlist->Ids[cidi].String); 209 i2c_id = acpi_i2c_search(idlist->Ids[cidi].String);
210 } 210 }
211 if (i2c_id != NULL) { 211 if (i2c_id != NULL) {
212 if (i2c_id->compat != NULL) { 212 if (i2c_id->compat != NULL) {
213 prop_data_t data; 213 prop_data_t data;
214 data = prop_data_create_copy(i2c_id->compat, 214 data = prop_data_create_copy(i2c_id->compat,
215 i2c_id->compatlen); 215 i2c_id->compatlen);
216 prop_dictionary_set(dev, "compatible", data); 216 prop_dictionary_set(dev, "compatible", data);
217 prop_object_release(data); 217 prop_object_release(data);
218 } 218 }
219 if (i2c_id->parse != NULL) 219 if (i2c_id->parse != NULL)
220 i2c_id->parse(ad, dev); 220 i2c_id->parse(ad, dev);
221 } 221 }
222 prop_array_add(array, dev); 222 prop_array_add(array, dev);
223 prop_object_release(dev); 223 prop_object_release(dev);
224} 224}
225 225
226 226
227prop_array_t 227prop_array_t
228acpi_enter_i2c_devs(struct acpi_devnode *devnode) 228acpi_enter_i2c_devs(device_t dev, struct acpi_devnode *devnode)
229{ 229{
230 struct acpi_devnode *ad; 230 struct acpi_devnode *ad;
231 prop_array_t array = prop_array_create(); 231 prop_array_t array = prop_array_create();
232 232
233 if (array == NULL) 233 if (array == NULL)
234 return NULL; 234 return NULL;
235 235
236 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) { 236 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
237 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 237 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
238 continue; 238 continue;
239 if (!acpi_device_present(ad->ad_handle)) 239 if (!acpi_device_present(ad->ad_handle))
240 continue; 240 continue;
241 acpi_enter_i2c_device(ad, array); 241 acpi_enter_i2c_device(ad, array);
242 } 242 }
 243
 244 if (dev != NULL) {
 245 acpi_claim_childdevs(dev, devnode);
 246 }
 247
243 return array; 248 return array;
244} 249}

cvs diff -r1.9 -r1.10 src/sys/dev/acpi/acpi_util.h (switch to unified diff)

--- src/sys/dev/acpi/acpi_util.h 2021/01/14 14:35:53 1.9
+++ src/sys/dev/acpi/acpi_util.h 2021/01/26 00:19:53 1.10
@@ -1,105 +1,107 @@ @@ -1,105 +1,107 @@
1/* $NetBSD: acpi_util.h,v 1.9 2021/01/14 14:35:53 thorpej Exp $ */ 1/* $NetBSD: acpi_util.h,v 1.10 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc. 8 * by Charles M. Hannum of By Noon Software, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright 2001, 2003 Wasabi Systems, Inc. 33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions 39 * modification, are permitted provided that the following conditions
40 * are met: 40 * are met:
41 * 1. Redistributions of source code must retain the above copyright 41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer. 42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright 43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the 44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution. 45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software 46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement: 47 * must display the following acknowledgement:
48 * This product includes software developed for the NetBSD Project by 48 * This product includes software developed for the NetBSD Project by
49 * Wasabi Systems, Inc. 49 * Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 * or promote products derived from this software without specific prior 51 * or promote products derived from this software without specific prior
52 * written permission. 52 * written permission.
53 * 53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE. 64 * POSSIBILITY OF SUCH DAMAGE.
65 */ 65 */
66 66
67#ifndef _SYS_DEV_ACPI_ACPI_UTIL_H 67#ifndef _SYS_DEV_ACPI_ACPI_UTIL_H
68#define _SYS_DEV_ACPI_ACPI_UTIL_H 68#define _SYS_DEV_ACPI_ACPI_UTIL_H
69 69
70ACPI_STATUS acpi_eval_integer(ACPI_HANDLE, const char *, ACPI_INTEGER *); 70ACPI_STATUS acpi_eval_integer(ACPI_HANDLE, const char *, ACPI_INTEGER *);
71ACPI_STATUS acpi_eval_set_integer(ACPI_HANDLE handle, const char *path, 71ACPI_STATUS acpi_eval_set_integer(ACPI_HANDLE handle, const char *path,
72 ACPI_INTEGER arg); 72 ACPI_INTEGER arg);
73ACPI_STATUS acpi_eval_string(ACPI_HANDLE, const char *, char **); 73ACPI_STATUS acpi_eval_string(ACPI_HANDLE, const char *, char **);
74ACPI_STATUS acpi_eval_struct(ACPI_HANDLE, const char *, ACPI_BUFFER *); 74ACPI_STATUS acpi_eval_struct(ACPI_HANDLE, const char *, ACPI_BUFFER *);
75ACPI_STATUS acpi_eval_reference_handle(ACPI_OBJECT *, ACPI_HANDLE *); 75ACPI_STATUS acpi_eval_reference_handle(ACPI_OBJECT *, ACPI_HANDLE *);
76 76
77ACPI_STATUS acpi_foreach_package_object(ACPI_OBJECT *, 77ACPI_STATUS acpi_foreach_package_object(ACPI_OBJECT *,
78 ACPI_STATUS (*)(ACPI_OBJECT *, void *), void *); 78 ACPI_STATUS (*)(ACPI_OBJECT *, void *), void *);
79ACPI_STATUS acpi_get(ACPI_HANDLE, ACPI_BUFFER *, 79ACPI_STATUS acpi_get(ACPI_HANDLE, ACPI_BUFFER *,
80 ACPI_STATUS (*)(ACPI_HANDLE, ACPI_BUFFER *)); 80 ACPI_STATUS (*)(ACPI_HANDLE, ACPI_BUFFER *));
81 81
82struct acpi_devnode *acpi_match_node(ACPI_HANDLE handle); 82struct acpi_devnode *acpi_match_node(ACPI_HANDLE handle);
83void acpi_match_node_init(struct acpi_devnode *ad); 83void acpi_match_node_init(struct acpi_devnode *ad);
84 84
85const char *acpi_name(ACPI_HANDLE); 85const char *acpi_name(ACPI_HANDLE);
86int acpi_match_hid(ACPI_DEVICE_INFO *, const char * const *); 86int acpi_match_hid(ACPI_DEVICE_INFO *, const char * const *);
87int acpi_match_class(ACPI_HANDLE, uint8_t, uint8_t, uint8_t); 87int acpi_match_class(ACPI_HANDLE, uint8_t, uint8_t, uint8_t);
88ACPI_HANDLE acpi_match_cpu_info(struct cpu_info *); 88ACPI_HANDLE acpi_match_cpu_info(struct cpu_info *);
89struct cpu_info *acpi_match_cpu_handle(ACPI_HANDLE); 89struct cpu_info *acpi_match_cpu_handle(ACPI_HANDLE);
90 90
91char *acpi_pack_compat_list(ACPI_DEVICE_INFO *, size_t *); 91char *acpi_pack_compat_list(ACPI_DEVICE_INFO *, size_t *);
92 92
93ACPI_STATUS acpi_dsd_integer(ACPI_HANDLE, const char *, ACPI_INTEGER *); 93ACPI_STATUS acpi_dsd_integer(ACPI_HANDLE, const char *, ACPI_INTEGER *);
94ACPI_STATUS acpi_dsd_string(ACPI_HANDLE, const char *, char **); 94ACPI_STATUS acpi_dsd_string(ACPI_HANDLE, const char *, char **);
95 95
96ACPI_STATUS acpi_dsm(ACPI_HANDLE, uint8_t *, ACPI_INTEGER, 96ACPI_STATUS acpi_dsm(ACPI_HANDLE, uint8_t *, ACPI_INTEGER,
97 ACPI_INTEGER, const ACPI_OBJECT *, ACPI_OBJECT **); 97 ACPI_INTEGER, const ACPI_OBJECT *, ACPI_OBJECT **);
98ACPI_STATUS acpi_dsm_typed(ACPI_HANDLE, uint8_t *, ACPI_INTEGER, 98ACPI_STATUS acpi_dsm_typed(ACPI_HANDLE, uint8_t *, ACPI_INTEGER,
99 ACPI_INTEGER, const ACPI_OBJECT *, 99 ACPI_INTEGER, const ACPI_OBJECT *,
100 ACPI_OBJECT_TYPE, ACPI_OBJECT **); 100 ACPI_OBJECT_TYPE, ACPI_OBJECT **);
101ACPI_STATUS acpi_dsm_integer(ACPI_HANDLE, uint8_t *, ACPI_INTEGER, 101ACPI_STATUS acpi_dsm_integer(ACPI_HANDLE, uint8_t *, ACPI_INTEGER,
102 ACPI_INTEGER, const ACPI_OBJECT *, 102 ACPI_INTEGER, const ACPI_OBJECT *,
103 ACPI_INTEGER *); 103 ACPI_INTEGER *);
104 104
 105ACPI_STATUS acpi_claim_childdevs(device_t, struct acpi_devnode *);
 106
105#endif /* !_SYS_DEV_ACPI_ACPI_UTIL_H */ 107#endif /* !_SYS_DEV_ACPI_ACPI_UTIL_H */

cvs diff -r1.1 -r1.2 src/sys/dev/acpi/acpi_i2c.h (switch to unified diff)

--- src/sys/dev/acpi/acpi_i2c.h 2017/12/10 16:51:30 1.1
+++ src/sys/dev/acpi/acpi_i2c.h 2021/01/26 00:19:53 1.2
@@ -1,38 +1,38 @@ @@ -1,38 +1,38 @@
1/* $NetBSD: acpi_i2c.h,v 1.1 2017/12/10 16:51:30 bouyer Exp $ */ 1/* $NetBSD: acpi_i2c.h,v 1.2 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Manuel Bouyer. 8 * by Manuel Bouyer.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 32
33#ifndef _SYS_DEV_ACPI_ACPI_I2C_H 33#ifndef _SYS_DEV_ACPI_ACPI_I2C_H
34#define _SYS_DEV_ACPI_ACPI_I2C_H 34#define _SYS_DEV_ACPI_ACPI_I2C_H
35#include <prop/proplib.h> 35#include <prop/proplib.h>
36 36
37prop_array_t acpi_enter_i2c_devs(struct acpi_devnode *); 37prop_array_t acpi_enter_i2c_devs(device_t, struct acpi_devnode *);
38#endif /* _SYS_DEV_ACPI_ACPI_I2C_H */ 38#endif /* _SYS_DEV_ACPI_ACPI_I2C_H */

cvs diff -r1.20 -r1.21 src/sys/dev/acpi/acpi_util.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_util.c 2021/01/14 14:35:53 1.20
+++ src/sys/dev/acpi/acpi_util.c 2021/01/26 00:19:53 1.21
@@ -1,866 +1,882 @@ @@ -1,866 +1,882 @@
1/* $NetBSD: acpi_util.c,v 1.20 2021/01/14 14:35:53 thorpej Exp $ */ 1/* $NetBSD: acpi_util.c,v 1.21 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2007, 2021 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2007, 2021 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc. 8 * by Charles M. Hannum of By Noon Software, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright 2001, 2003 Wasabi Systems, Inc. 33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions 39 * modification, are permitted provided that the following conditions
40 * are met: 40 * are met:
41 * 1. Redistributions of source code must retain the above copyright 41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer. 42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright 43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the 44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution. 45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software 46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement: 47 * must display the following acknowledgement:
48 * This product includes software developed for the NetBSD Project by 48 * This product includes software developed for the NetBSD Project by
49 * Wasabi Systems, Inc. 49 * Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 * or promote products derived from this software without specific prior 51 * or promote products derived from this software without specific prior
52 * written permission. 52 * written permission.
53 * 53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE. 64 * POSSIBILITY OF SUCH DAMAGE.
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.20 2021/01/14 14:35:53 thorpej Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.21 2021/01/26 00:19:53 jmcneill Exp $");
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/kmem.h> 71#include <sys/kmem.h>
72#include <sys/cpu.h> 72#include <sys/cpu.h>
73 73
74#include <dev/acpi/acpireg.h> 74#include <dev/acpi/acpireg.h>
75#include <dev/acpi/acpivar.h> 75#include <dev/acpi/acpivar.h>
76#include <dev/acpi/acpi_intr.h> 76#include <dev/acpi/acpi_intr.h>
77 77
78#include <machine/acpi_machdep.h> 78#include <machine/acpi_machdep.h>
79 79
80#define _COMPONENT ACPI_BUS_COMPONENT 80#define _COMPONENT ACPI_BUS_COMPONENT
81ACPI_MODULE_NAME ("acpi_util") 81ACPI_MODULE_NAME ("acpi_util")
82 82
83static void acpi_clean_node(ACPI_HANDLE, void *); 83static void acpi_clean_node(ACPI_HANDLE, void *);
84 84
85static const char * const acpicpu_ids[] = { 85static const char * const acpicpu_ids[] = {
86 "ACPI0007", 86 "ACPI0007",
87 NULL 87 NULL
88}; 88};
89 89
90/* 90/*
91 * Evaluate an integer object. 91 * Evaluate an integer object.
92 */ 92 */
93ACPI_STATUS 93ACPI_STATUS
94acpi_eval_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER *valp) 94acpi_eval_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER *valp)
95{ 95{
96 ACPI_OBJECT obj; 96 ACPI_OBJECT obj;
97 ACPI_BUFFER buf; 97 ACPI_BUFFER buf;
98 ACPI_STATUS rv; 98 ACPI_STATUS rv;
99 99
100 if (handle == NULL) 100 if (handle == NULL)
101 handle = ACPI_ROOT_OBJECT; 101 handle = ACPI_ROOT_OBJECT;
102 102
103 (void)memset(&obj, 0, sizeof(obj)); 103 (void)memset(&obj, 0, sizeof(obj));
104 buf.Pointer = &obj; 104 buf.Pointer = &obj;
105 buf.Length = sizeof(obj); 105 buf.Length = sizeof(obj);
106 106
107 rv = AcpiEvaluateObject(handle, path, NULL, &buf); 107 rv = AcpiEvaluateObject(handle, path, NULL, &buf);
108 108
109 if (ACPI_FAILURE(rv)) 109 if (ACPI_FAILURE(rv))
110 return rv; 110 return rv;
111 111
112 /* Check that evaluation produced a return value. */ 112 /* Check that evaluation produced a return value. */
113 if (buf.Length == 0) 113 if (buf.Length == 0)
114 return AE_NULL_OBJECT; 114 return AE_NULL_OBJECT;
115 115
116 if (obj.Type != ACPI_TYPE_INTEGER) 116 if (obj.Type != ACPI_TYPE_INTEGER)
117 return AE_TYPE; 117 return AE_TYPE;
118 118
119 if (valp != NULL) 119 if (valp != NULL)
120 *valp = obj.Integer.Value; 120 *valp = obj.Integer.Value;
121 121
122 return AE_OK; 122 return AE_OK;
123} 123}
124 124
125/* 125/*
126 * Evaluate an integer object with a single integer input parameter. 126 * Evaluate an integer object with a single integer input parameter.
127 */ 127 */
128ACPI_STATUS 128ACPI_STATUS
129acpi_eval_set_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER val) 129acpi_eval_set_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER val)
130{ 130{
131 ACPI_OBJECT_LIST arg; 131 ACPI_OBJECT_LIST arg;
132 ACPI_OBJECT obj; 132 ACPI_OBJECT obj;
133 133
134 if (handle == NULL) 134 if (handle == NULL)
135 handle = ACPI_ROOT_OBJECT; 135 handle = ACPI_ROOT_OBJECT;
136 136
137 obj.Type = ACPI_TYPE_INTEGER; 137 obj.Type = ACPI_TYPE_INTEGER;
138 obj.Integer.Value = val; 138 obj.Integer.Value = val;
139 139
140 arg.Count = 1; 140 arg.Count = 1;
141 arg.Pointer = &obj; 141 arg.Pointer = &obj;
142 142
143 return AcpiEvaluateObject(handle, path, &arg, NULL); 143 return AcpiEvaluateObject(handle, path, &arg, NULL);
144} 144}
145 145
146/* 146/*
147 * Evaluate a (Unicode) string object. 147 * Evaluate a (Unicode) string object.
148 */ 148 */
149ACPI_STATUS 149ACPI_STATUS
150acpi_eval_string(ACPI_HANDLE handle, const char *path, char **stringp) 150acpi_eval_string(ACPI_HANDLE handle, const char *path, char **stringp)
151{ 151{
152 ACPI_OBJECT *obj; 152 ACPI_OBJECT *obj;
153 ACPI_BUFFER buf; 153 ACPI_BUFFER buf;
154 ACPI_STATUS rv; 154 ACPI_STATUS rv;
155 155
156 rv = acpi_eval_struct(handle, path, &buf); 156 rv = acpi_eval_struct(handle, path, &buf);
157 157
158 if (ACPI_FAILURE(rv)) 158 if (ACPI_FAILURE(rv))
159 return rv; 159 return rv;
160 160
161 obj = buf.Pointer; 161 obj = buf.Pointer;
162 162
163 if (obj->Type != ACPI_TYPE_STRING) { 163 if (obj->Type != ACPI_TYPE_STRING) {
164 rv = AE_TYPE; 164 rv = AE_TYPE;
165 goto out; 165 goto out;
166 } 166 }
167 167
168 if (obj->String.Length == 0) { 168 if (obj->String.Length == 0) {
169 rv = AE_BAD_DATA; 169 rv = AE_BAD_DATA;
170 goto out; 170 goto out;
171 } 171 }
172 172
173 *stringp = ACPI_ALLOCATE(obj->String.Length + 1); 173 *stringp = ACPI_ALLOCATE(obj->String.Length + 1);
174 174
175 if (*stringp == NULL) { 175 if (*stringp == NULL) {
176 rv = AE_NO_MEMORY; 176 rv = AE_NO_MEMORY;
177 goto out; 177 goto out;
178 } 178 }
179 179
180 (void)memcpy(*stringp, obj->String.Pointer, obj->String.Length); 180 (void)memcpy(*stringp, obj->String.Pointer, obj->String.Length);
181 181
182 (*stringp)[obj->String.Length] = '\0'; 182 (*stringp)[obj->String.Length] = '\0';
183 183
184out: 184out:
185 ACPI_FREE(buf.Pointer); 185 ACPI_FREE(buf.Pointer);
186 186
187 return rv; 187 return rv;
188} 188}
189 189
190/* 190/*
191 * Evaluate a structure. Caller must free buf.Pointer by ACPI_FREE(). 191 * Evaluate a structure. Caller must free buf.Pointer by ACPI_FREE().
192 */ 192 */
193ACPI_STATUS 193ACPI_STATUS
194acpi_eval_struct(ACPI_HANDLE handle, const char *path, ACPI_BUFFER *buf) 194acpi_eval_struct(ACPI_HANDLE handle, const char *path, ACPI_BUFFER *buf)
195{ 195{
196 196
197 if (handle == NULL) 197 if (handle == NULL)
198 handle = ACPI_ROOT_OBJECT; 198 handle = ACPI_ROOT_OBJECT;
199 199
200 buf->Pointer = NULL; 200 buf->Pointer = NULL;
201 buf->Length = ACPI_ALLOCATE_LOCAL_BUFFER; 201 buf->Length = ACPI_ALLOCATE_LOCAL_BUFFER;
202 202
203 return AcpiEvaluateObject(handle, path, NULL, buf); 203 return AcpiEvaluateObject(handle, path, NULL, buf);
204} 204}
205 205
206/* 206/*
207 * Evaluate a reference handle from an element in a package. 207 * Evaluate a reference handle from an element in a package.
208 */ 208 */
209ACPI_STATUS 209ACPI_STATUS
210acpi_eval_reference_handle(ACPI_OBJECT *elm, ACPI_HANDLE *handle) 210acpi_eval_reference_handle(ACPI_OBJECT *elm, ACPI_HANDLE *handle)
211{ 211{
212 212
213 if (elm == NULL || handle == NULL) 213 if (elm == NULL || handle == NULL)
214 return AE_BAD_PARAMETER; 214 return AE_BAD_PARAMETER;
215 215
216 switch (elm->Type) { 216 switch (elm->Type) {
217 217
218 case ACPI_TYPE_ANY: 218 case ACPI_TYPE_ANY:
219 case ACPI_TYPE_LOCAL_REFERENCE: 219 case ACPI_TYPE_LOCAL_REFERENCE:
220 220
221 if (elm->Reference.Handle == NULL) 221 if (elm->Reference.Handle == NULL)
222 return AE_NULL_ENTRY; 222 return AE_NULL_ENTRY;
223 223
224 *handle = elm->Reference.Handle; 224 *handle = elm->Reference.Handle;
225 225
226 return AE_OK; 226 return AE_OK;
227 227
228 case ACPI_TYPE_STRING: 228 case ACPI_TYPE_STRING:
229 return AcpiGetHandle(NULL, elm->String.Pointer, handle); 229 return AcpiGetHandle(NULL, elm->String.Pointer, handle);
230 230
231 default: 231 default:
232 return AE_TYPE; 232 return AE_TYPE;
233 } 233 }
234} 234}
235 235
236/* 236/*
237 * Iterate over all objects in a package, and pass them all 237 * Iterate over all objects in a package, and pass them all
238 * to a function. If the called function returns non-AE_OK, 238 * to a function. If the called function returns non-AE_OK,
239 * the iteration is stopped and that value is returned. 239 * the iteration is stopped and that value is returned.
240 */ 240 */
241ACPI_STATUS 241ACPI_STATUS
242acpi_foreach_package_object(ACPI_OBJECT *pkg, 242acpi_foreach_package_object(ACPI_OBJECT *pkg,
243 ACPI_STATUS (*func)(ACPI_OBJECT *, void *), void *arg) 243 ACPI_STATUS (*func)(ACPI_OBJECT *, void *), void *arg)
244{ 244{
245 ACPI_STATUS rv = AE_OK; 245 ACPI_STATUS rv = AE_OK;
246 uint32_t i; 246 uint32_t i;
247 247
248 if (pkg == NULL) 248 if (pkg == NULL)
249 return AE_BAD_PARAMETER; 249 return AE_BAD_PARAMETER;
250 250
251 if (pkg->Type != ACPI_TYPE_PACKAGE) 251 if (pkg->Type != ACPI_TYPE_PACKAGE)
252 return AE_TYPE; 252 return AE_TYPE;
253 253
254 for (i = 0; i < pkg->Package.Count; i++) { 254 for (i = 0; i < pkg->Package.Count; i++) {
255 255
256 rv = (*func)(&pkg->Package.Elements[i], arg); 256 rv = (*func)(&pkg->Package.Elements[i], arg);
257 257
258 if (ACPI_FAILURE(rv)) 258 if (ACPI_FAILURE(rv))
259 break; 259 break;
260 } 260 }
261 261
262 return rv; 262 return rv;
263} 263}
264 264
265/* 265/*
266 * Fetch data info the specified (empty) ACPI buffer. 266 * Fetch data info the specified (empty) ACPI buffer.
267 * Caller must free buf.Pointer by ACPI_FREE(). 267 * Caller must free buf.Pointer by ACPI_FREE().
268 */ 268 */
269ACPI_STATUS 269ACPI_STATUS
270acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf, 270acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf,
271 ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *)) 271 ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *))
272{ 272{
273 273
274 buf->Pointer = NULL; 274 buf->Pointer = NULL;
275 buf->Length = ACPI_ALLOCATE_LOCAL_BUFFER; 275 buf->Length = ACPI_ALLOCATE_LOCAL_BUFFER;
276 276
277 return (*getit)(handle, buf); 277 return (*getit)(handle, buf);
278} 278}
279 279
280/* 280/*
281 * Return a complete pathname from a handle. 281 * Return a complete pathname from a handle.
282 * 282 *
283 * Note that the function uses static data storage; 283 * Note that the function uses static data storage;
284 * if the data is needed for future use, it should be 284 * if the data is needed for future use, it should be
285 * copied before any subsequent calls overwrite it. 285 * copied before any subsequent calls overwrite it.
286 */ 286 */
287const char * 287const char *
288acpi_name(ACPI_HANDLE handle) 288acpi_name(ACPI_HANDLE handle)
289{ 289{
290 static char name[80]; 290 static char name[80];
291 ACPI_BUFFER buf; 291 ACPI_BUFFER buf;
292 ACPI_STATUS rv; 292 ACPI_STATUS rv;
293 293
294 if (handle == NULL) 294 if (handle == NULL)
295 handle = ACPI_ROOT_OBJECT; 295 handle = ACPI_ROOT_OBJECT;
296 296
297 buf.Pointer = name; 297 buf.Pointer = name;
298 buf.Length = sizeof(name); 298 buf.Length = sizeof(name);
299 299
300 rv = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf); 300 rv = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf);
301 301
302 if (ACPI_FAILURE(rv)) 302 if (ACPI_FAILURE(rv))
303 return "UNKNOWN"; 303 return "UNKNOWN";
304 304
305 return name; 305 return name;
306} 306}
307 307
308/* 308/*
309 * Pack _HID and _CID ID strings into an OpenFirmware-like 309 * Pack _HID and _CID ID strings into an OpenFirmware-like
310 * string list. 310 * string list.
311 */ 311 */
312char * 312char *
313acpi_pack_compat_list(ACPI_DEVICE_INFO *ad, size_t *sizep) 313acpi_pack_compat_list(ACPI_DEVICE_INFO *ad, size_t *sizep)
314{ 314{
315 KASSERT(sizep != NULL); 315 KASSERT(sizep != NULL);
316 316
317 char *strlist, *cp; 317 char *strlist, *cp;
318 size_t len = 0; 318 size_t len = 0;
319 uint32_t i; 319 uint32_t i;
320 320
321 /* 321 /*
322 * First calculate the total size required. 322 * First calculate the total size required.
323 * N.B. PNP Device ID length includes terminating NUL. 323 * N.B. PNP Device ID length includes terminating NUL.
324 */ 324 */
325 if ((ad->Valid & ACPI_VALID_HID) != 0) { 325 if ((ad->Valid & ACPI_VALID_HID) != 0) {
326 len += ad->HardwareId.Length; 326 len += ad->HardwareId.Length;
327 } 327 }
328 328
329 if ((ad->Valid & ACPI_VALID_CID) != 0) { 329 if ((ad->Valid & ACPI_VALID_CID) != 0) {
330 for (i = 0; i < ad->CompatibleIdList.Count; i++) { 330 for (i = 0; i < ad->CompatibleIdList.Count; i++) {
331 len += ad->CompatibleIdList.Ids[i].Length; 331 len += ad->CompatibleIdList.Ids[i].Length;
332 } 332 }
333 } 333 }
334 334
335 *sizep = len; 335 *sizep = len;
336 if (len == 0) { 336 if (len == 0) {
337 return NULL; 337 return NULL;
338 } 338 }
339 339
340 cp = strlist = kmem_alloc(len, KM_SLEEP); 340 cp = strlist = kmem_alloc(len, KM_SLEEP);
341 341
342 if ((ad->Valid & ACPI_VALID_HID) != 0) { 342 if ((ad->Valid & ACPI_VALID_HID) != 0) {
343 memcpy(cp, ad->HardwareId.String, ad->HardwareId.Length); 343 memcpy(cp, ad->HardwareId.String, ad->HardwareId.Length);
344 cp += ad->HardwareId.Length; 344 cp += ad->HardwareId.Length;
345 } 345 }
346 346
347 if ((ad->Valid & ACPI_VALID_CID) != 0) { 347 if ((ad->Valid & ACPI_VALID_CID) != 0) {
348 for (i = 0; i < ad->CompatibleIdList.Count; i++) { 348 for (i = 0; i < ad->CompatibleIdList.Count; i++) {
349 memcpy(cp, ad->CompatibleIdList.Ids[i].String, 349 memcpy(cp, ad->CompatibleIdList.Ids[i].String,
350 ad->CompatibleIdList.Ids[i].Length); 350 ad->CompatibleIdList.Ids[i].Length);
351 cp += ad->CompatibleIdList.Ids[i].Length; 351 cp += ad->CompatibleIdList.Ids[i].Length;
352 } 352 }
353 } 353 }
354 354
355 KASSERT((size_t)(cp - strlist) == len); 355 KASSERT((size_t)(cp - strlist) == len);
356 356
357 return strlist; 357 return strlist;
358} 358}
359 359
360 360
361/* 361/*
362 * Match given IDs against _HID and _CIDs. 362 * Match given IDs against _HID and _CIDs.
363 */ 363 */
364int 364int
365acpi_match_hid(ACPI_DEVICE_INFO *ad, const char * const *ids) 365acpi_match_hid(ACPI_DEVICE_INFO *ad, const char * const *ids)
366{ 366{
367 uint32_t i, n; 367 uint32_t i, n;
368 char *id; 368 char *id;
369 369
370 while (*ids) { 370 while (*ids) {
371 371
372 if ((ad->Valid & ACPI_VALID_HID) != 0) { 372 if ((ad->Valid & ACPI_VALID_HID) != 0) {
373 373
374 if (pmatch(ad->HardwareId.String, *ids, NULL) == 2) 374 if (pmatch(ad->HardwareId.String, *ids, NULL) == 2)
375 return 1; 375 return 1;
376 } 376 }
377 377
378 if ((ad->Valid & ACPI_VALID_CID) != 0) { 378 if ((ad->Valid & ACPI_VALID_CID) != 0) {
379 379
380 n = ad->CompatibleIdList.Count; 380 n = ad->CompatibleIdList.Count;
381 381
382 for (i = 0; i < n; i++) { 382 for (i = 0; i < n; i++) {
383 383
384 id = ad->CompatibleIdList.Ids[i].String; 384 id = ad->CompatibleIdList.Ids[i].String;
385 385
386 if (pmatch(id, *ids, NULL) == 2) 386 if (pmatch(id, *ids, NULL) == 2)
387 return 1; 387 return 1;
388 } 388 }
389 } 389 }
390 390
391 ids++; 391 ids++;
392 } 392 }
393 393
394 return 0; 394 return 0;
395} 395}
396 396
397/* 397/*
398 * Match a PCI-defined bass-class, sub-class, and programming interface 398 * Match a PCI-defined bass-class, sub-class, and programming interface
399 * against a handle's _CLS object. 399 * against a handle's _CLS object.
400 */ 400 */
401int 401int
402acpi_match_class(ACPI_HANDLE handle, uint8_t pci_class, uint8_t pci_subclass, 402acpi_match_class(ACPI_HANDLE handle, uint8_t pci_class, uint8_t pci_subclass,
403 uint8_t pci_interface) 403 uint8_t pci_interface)
404{ 404{
405 ACPI_BUFFER buf; 405 ACPI_BUFFER buf;
406 ACPI_OBJECT *obj; 406 ACPI_OBJECT *obj;
407 ACPI_STATUS rv; 407 ACPI_STATUS rv;
408 int match = 0; 408 int match = 0;
409 409
410 rv = acpi_eval_struct(handle, "_CLS", &buf); 410 rv = acpi_eval_struct(handle, "_CLS", &buf);
411 if (ACPI_FAILURE(rv)) 411 if (ACPI_FAILURE(rv))
412 goto done; 412 goto done;
413 413
414 obj = buf.Pointer; 414 obj = buf.Pointer;
415 if (obj->Type != ACPI_TYPE_PACKAGE) 415 if (obj->Type != ACPI_TYPE_PACKAGE)
416 goto done; 416 goto done;
417 if (obj->Package.Count != 3) 417 if (obj->Package.Count != 3)
418 goto done; 418 goto done;
419 if (obj->Package.Elements[0].Type != ACPI_TYPE_INTEGER || 419 if (obj->Package.Elements[0].Type != ACPI_TYPE_INTEGER ||
420 obj->Package.Elements[1].Type != ACPI_TYPE_INTEGER || 420 obj->Package.Elements[1].Type != ACPI_TYPE_INTEGER ||
421 obj->Package.Elements[2].Type != ACPI_TYPE_INTEGER) 421 obj->Package.Elements[2].Type != ACPI_TYPE_INTEGER)
422 goto done; 422 goto done;
423 423
424 match = obj->Package.Elements[0].Integer.Value == pci_class && 424 match = obj->Package.Elements[0].Integer.Value == pci_class &&
425 obj->Package.Elements[1].Integer.Value == pci_subclass && 425 obj->Package.Elements[1].Integer.Value == pci_subclass &&
426 obj->Package.Elements[2].Integer.Value == pci_interface; 426 obj->Package.Elements[2].Integer.Value == pci_interface;
427 427
428done: 428done:
429 if (buf.Pointer) 429 if (buf.Pointer)
430 ACPI_FREE(buf.Pointer); 430 ACPI_FREE(buf.Pointer);
431 return match; 431 return match;
432} 432}
433 433
434/* 434/*
435 * Match a device node from a handle. 435 * Match a device node from a handle.
436 */ 436 */
437struct acpi_devnode * 437struct acpi_devnode *
438acpi_match_node(ACPI_HANDLE handle) 438acpi_match_node(ACPI_HANDLE handle)
439{ 439{
440 struct acpi_devnode *ad; 440 struct acpi_devnode *ad;
441 ACPI_STATUS rv; 441 ACPI_STATUS rv;
442 442
443 if (handle == NULL) 443 if (handle == NULL)
444 return NULL; 444 return NULL;
445 445
446 rv = AcpiGetData(handle, acpi_clean_node, (void **)&ad); 446 rv = AcpiGetData(handle, acpi_clean_node, (void **)&ad);
447 447
448 if (ACPI_FAILURE(rv)) 448 if (ACPI_FAILURE(rv))
449 return NULL; 449 return NULL;
450 450
451 return ad; 451 return ad;
452} 452}
453 453
454/* 454/*
455 * Permanently associate a device node with a handle. 455 * Permanently associate a device node with a handle.
456 */ 456 */
457void 457void
458acpi_match_node_init(struct acpi_devnode *ad) 458acpi_match_node_init(struct acpi_devnode *ad)
459{ 459{
460 (void)AcpiAttachData(ad->ad_handle, acpi_clean_node, ad); 460 (void)AcpiAttachData(ad->ad_handle, acpi_clean_node, ad);
461} 461}
462 462
463static void 463static void
464acpi_clean_node(ACPI_HANDLE handle, void *aux) 464acpi_clean_node(ACPI_HANDLE handle, void *aux)
465{ 465{
466 /* Nothing. */ 466 /* Nothing. */
467} 467}
468 468
469/* 469/*
470 * Match a handle from a cpu_info. Returns NULL on failure. 470 * Match a handle from a cpu_info. Returns NULL on failure.
471 * 471 *
472 * Note that acpi_match_node() can be used if the device node 472 * Note that acpi_match_node() can be used if the device node
473 * is also required. 473 * is also required.
474 */ 474 */
475ACPI_HANDLE 475ACPI_HANDLE
476acpi_match_cpu_info(struct cpu_info *ci) 476acpi_match_cpu_info(struct cpu_info *ci)
477{ 477{
478 struct acpi_softc *sc = acpi_softc; 478 struct acpi_softc *sc = acpi_softc;
479 struct acpi_devnode *ad; 479 struct acpi_devnode *ad;
480 ACPI_INTEGER val; 480 ACPI_INTEGER val;
481 ACPI_OBJECT *obj; 481 ACPI_OBJECT *obj;
482 ACPI_BUFFER buf; 482 ACPI_BUFFER buf;
483 ACPI_HANDLE hdl; 483 ACPI_HANDLE hdl;
484 ACPI_STATUS rv; 484 ACPI_STATUS rv;
485 485
486 if (sc == NULL || acpi_active == 0) 486 if (sc == NULL || acpi_active == 0)
487 return NULL; 487 return NULL;
488 488
489 /* 489 /*
490 * CPUs are declared in the ACPI namespace 490 * CPUs are declared in the ACPI namespace
491 * either as a Processor() or as a Device(). 491 * either as a Processor() or as a Device().
492 * In both cases the MADT entries are used 492 * In both cases the MADT entries are used
493 * for the match (see ACPI 4.0, section 8.4). 493 * for the match (see ACPI 4.0, section 8.4).
494 */ 494 */
495 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 495 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
496 496
497 hdl = ad->ad_handle; 497 hdl = ad->ad_handle;
498 498
499 switch (ad->ad_type) { 499 switch (ad->ad_type) {
500 500
501 case ACPI_TYPE_DEVICE: 501 case ACPI_TYPE_DEVICE:
502 502
503 if (acpi_match_hid(ad->ad_devinfo, acpicpu_ids) == 0) 503 if (acpi_match_hid(ad->ad_devinfo, acpicpu_ids) == 0)
504 break; 504 break;
505 505
506 rv = acpi_eval_integer(hdl, "_UID", &val); 506 rv = acpi_eval_integer(hdl, "_UID", &val);
507 507
508 if (ACPI_SUCCESS(rv) && val == ci->ci_acpiid) 508 if (ACPI_SUCCESS(rv) && val == ci->ci_acpiid)
509 return hdl; 509 return hdl;
510 510
511 break; 511 break;
512 512
513 case ACPI_TYPE_PROCESSOR: 513 case ACPI_TYPE_PROCESSOR:
514 514
515 rv = acpi_eval_struct(hdl, NULL, &buf); 515 rv = acpi_eval_struct(hdl, NULL, &buf);
516 516
517 if (ACPI_FAILURE(rv)) 517 if (ACPI_FAILURE(rv))
518 break; 518 break;
519 519
520 obj = buf.Pointer; 520 obj = buf.Pointer;
521 521
522 if (obj->Processor.ProcId == ci->ci_acpiid) { 522 if (obj->Processor.ProcId == ci->ci_acpiid) {
523 ACPI_FREE(buf.Pointer); 523 ACPI_FREE(buf.Pointer);
524 return hdl; 524 return hdl;
525 } 525 }
526 526
527 ACPI_FREE(buf.Pointer); 527 ACPI_FREE(buf.Pointer);
528 break; 528 break;
529 } 529 }
530 } 530 }
531 531
532 return NULL; 532 return NULL;
533} 533}
534 534
535/* 535/*
536 * Match a CPU from a handle. Returns NULL on failure. 536 * Match a CPU from a handle. Returns NULL on failure.
537 */ 537 */
538struct cpu_info * 538struct cpu_info *
539acpi_match_cpu_handle(ACPI_HANDLE hdl) 539acpi_match_cpu_handle(ACPI_HANDLE hdl)
540{ 540{
541 struct cpu_info *ci; 541 struct cpu_info *ci;
542 ACPI_DEVICE_INFO *di; 542 ACPI_DEVICE_INFO *di;
543 CPU_INFO_ITERATOR cii; 543 CPU_INFO_ITERATOR cii;
544 ACPI_INTEGER val; 544 ACPI_INTEGER val;
545 ACPI_OBJECT *obj; 545 ACPI_OBJECT *obj;
546 ACPI_BUFFER buf; 546 ACPI_BUFFER buf;
547 ACPI_STATUS rv; 547 ACPI_STATUS rv;
548 548
549 ci = NULL; 549 ci = NULL;
550 di = NULL; 550 di = NULL;
551 buf.Pointer = NULL; 551 buf.Pointer = NULL;
552 552
553 rv = AcpiGetObjectInfo(hdl, &di); 553 rv = AcpiGetObjectInfo(hdl, &di);
554 554
555 if (ACPI_FAILURE(rv)) 555 if (ACPI_FAILURE(rv))
556 return NULL; 556 return NULL;
557 557
558 switch (di->Type) { 558 switch (di->Type) {
559 559
560 case ACPI_TYPE_DEVICE: 560 case ACPI_TYPE_DEVICE:
561 561
562 if (acpi_match_hid(di, acpicpu_ids) == 0) 562 if (acpi_match_hid(di, acpicpu_ids) == 0)
563 goto out; 563 goto out;
564 564
565 rv = acpi_eval_integer(hdl, "_UID", &val); 565 rv = acpi_eval_integer(hdl, "_UID", &val);
566 566
567 if (ACPI_FAILURE(rv)) 567 if (ACPI_FAILURE(rv))
568 goto out; 568 goto out;
569 569
570 break; 570 break;
571 571
572 case ACPI_TYPE_PROCESSOR: 572 case ACPI_TYPE_PROCESSOR:
573 573
574 rv = acpi_eval_struct(hdl, NULL, &buf); 574 rv = acpi_eval_struct(hdl, NULL, &buf);
575 575
576 if (ACPI_FAILURE(rv)) 576 if (ACPI_FAILURE(rv))
577 goto out; 577 goto out;
578 578
579 obj = buf.Pointer; 579 obj = buf.Pointer;
580 val = obj->Processor.ProcId; 580 val = obj->Processor.ProcId;
581 break; 581 break;
582 582
583 default: 583 default:
584 goto out; 584 goto out;
585 } 585 }
586 586
587 for (CPU_INFO_FOREACH(cii, ci)) { 587 for (CPU_INFO_FOREACH(cii, ci)) {
588 588
589 if (ci->ci_acpiid == val) 589 if (ci->ci_acpiid == val)
590 goto out; 590 goto out;
591 } 591 }
592 592
593 ci = NULL; 593 ci = NULL;
594 594
595out: 595out:
596 if (di != NULL) 596 if (di != NULL)
597 ACPI_FREE(di); 597 ACPI_FREE(di);
598 598
599 if (buf.Pointer != NULL) 599 if (buf.Pointer != NULL)
600 ACPI_FREE(buf.Pointer); 600 ACPI_FREE(buf.Pointer);
601 601
602 return ci; 602 return ci;
603} 603}
604 604
605struct acpi_irq_handler { 605struct acpi_irq_handler {
606 uint32_t aih_irq; 606 uint32_t aih_irq;
607 void *aih_ih; 607 void *aih_ih;
608}; 608};
609 609
610void * 610void *
611acpi_intr_establish(device_t dev, uint64_t c, int ipl, bool mpsafe, 611acpi_intr_establish(device_t dev, uint64_t c, int ipl, bool mpsafe,
612 int (*intr)(void *), void *iarg, const char *xname) 612 int (*intr)(void *), void *iarg, const char *xname)
613{ 613{
614 ACPI_STATUS rv; 614 ACPI_STATUS rv;
615 ACPI_HANDLE hdl = (void *)(uintptr_t)c; 615 ACPI_HANDLE hdl = (void *)(uintptr_t)c;
616 struct acpi_resources res; 616 struct acpi_resources res;
617 struct acpi_irq *irq; 617 struct acpi_irq *irq;
618 void *aih = NULL; 618 void *aih = NULL;
619 619
620 rv = acpi_resource_parse(dev, hdl, "_CRS", &res, 620 rv = acpi_resource_parse(dev, hdl, "_CRS", &res,
621 &acpi_resource_parse_ops_quiet); 621 &acpi_resource_parse_ops_quiet);
622 if (ACPI_FAILURE(rv)) 622 if (ACPI_FAILURE(rv))
623 return NULL; 623 return NULL;
624 624
625 irq = acpi_res_irq(&res, 0); 625 irq = acpi_res_irq(&res, 0);
626 if (irq == NULL) 626 if (irq == NULL)
627 goto end; 627 goto end;
628 628
629 aih = acpi_intr_establish_irq(dev, irq, ipl, mpsafe, 629 aih = acpi_intr_establish_irq(dev, irq, ipl, mpsafe,
630 intr, iarg, xname); 630 intr, iarg, xname);
631 631
632end: 632end:
633 acpi_resource_cleanup(&res); 633 acpi_resource_cleanup(&res);
634 634
635 return aih; 635 return aih;
636} 636}
637 637
638void * 638void *
639acpi_intr_establish_irq(device_t dev, struct acpi_irq *irq, int ipl, 639acpi_intr_establish_irq(device_t dev, struct acpi_irq *irq, int ipl,
640 bool mpsafe, int (*intr)(void *), void *iarg, const char *xname) 640 bool mpsafe, int (*intr)(void *), void *iarg, const char *xname)
641{ 641{
642 struct acpi_irq_handler *aih; 642 struct acpi_irq_handler *aih;
643 void *ih; 643 void *ih;
644 644
645 const int type = (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL; 645 const int type = (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL;
646 ih = acpi_md_intr_establish(irq->ar_irq, ipl, type, intr, iarg, mpsafe, xname); 646 ih = acpi_md_intr_establish(irq->ar_irq, ipl, type, intr, iarg, mpsafe, xname);
647 if (ih == NULL) 647 if (ih == NULL)
648 return NULL; 648 return NULL;
649 649
650 aih = kmem_alloc(sizeof(struct acpi_irq_handler), KM_SLEEP); 650 aih = kmem_alloc(sizeof(struct acpi_irq_handler), KM_SLEEP);
651 aih->aih_irq = irq->ar_irq; 651 aih->aih_irq = irq->ar_irq;
652 aih->aih_ih = ih; 652 aih->aih_ih = ih;
653 653
654 return aih; 654 return aih;
655} 655}
656 656
657void 657void
658acpi_intr_mask(void *c) 658acpi_intr_mask(void *c)
659{ 659{
660 struct acpi_irq_handler * const aih = c; 660 struct acpi_irq_handler * const aih = c;
661 661
662 acpi_md_intr_mask(aih->aih_ih); 662 acpi_md_intr_mask(aih->aih_ih);
663} 663}
664 664
665void 665void
666acpi_intr_unmask(void *c) 666acpi_intr_unmask(void *c)
667{ 667{
668 struct acpi_irq_handler * const aih = c; 668 struct acpi_irq_handler * const aih = c;
669 669
670 acpi_md_intr_unmask(aih->aih_ih); 670 acpi_md_intr_unmask(aih->aih_ih);
671} 671}
672 672
673void 673void
674acpi_intr_disestablish(void *c) 674acpi_intr_disestablish(void *c)
675{ 675{
676 struct acpi_irq_handler *aih = c; 676 struct acpi_irq_handler *aih = c;
677 677
678 acpi_md_intr_disestablish(aih->aih_ih); 678 acpi_md_intr_disestablish(aih->aih_ih);
679 kmem_free(aih, sizeof(struct acpi_irq_handler)); 679 kmem_free(aih, sizeof(struct acpi_irq_handler));
680} 680}
681 681
682const char * 682const char *
683acpi_intr_string(void *c, char *buf, size_t size) 683acpi_intr_string(void *c, char *buf, size_t size)
684{ 684{
685 struct acpi_irq_handler *aih = c; 685 struct acpi_irq_handler *aih = c;
686 intr_handle_t ih = aih->aih_irq; 686 intr_handle_t ih = aih->aih_irq;
687 687
688 return intr_string(ih, buf, size); 688 return intr_string(ih, buf, size);
689} 689}
690 690
691/* 691/*
692 * Device-Specific Data (_DSD) support 692 * Device-Specific Data (_DSD) support
693 */ 693 */
694 694
695static UINT8 acpi_dsd_uuid[ACPI_UUID_LENGTH] = { 695static UINT8 acpi_dsd_uuid[ACPI_UUID_LENGTH] = {
696 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d, 696 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
697 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 697 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01
698}; 698};
699 699
700static ACPI_STATUS 700static ACPI_STATUS
701acpi_dsd_property(ACPI_HANDLE handle, const char *prop, ACPI_BUFFER *pbuf, ACPI_OBJECT_TYPE type, ACPI_OBJECT **ret) 701acpi_dsd_property(ACPI_HANDLE handle, const char *prop, ACPI_BUFFER *pbuf, ACPI_OBJECT_TYPE type, ACPI_OBJECT **ret)
702{ 702{
703 ACPI_OBJECT *obj, *uuid, *props, *pobj, *propkey, *propval; 703 ACPI_OBJECT *obj, *uuid, *props, *pobj, *propkey, *propval;
704 ACPI_STATUS rv; 704 ACPI_STATUS rv;
705 int n; 705 int n;
706 706
707 rv = AcpiEvaluateObjectTyped(handle, "_DSD", NULL, pbuf, ACPI_TYPE_PACKAGE); 707 rv = AcpiEvaluateObjectTyped(handle, "_DSD", NULL, pbuf, ACPI_TYPE_PACKAGE);
708 if (ACPI_FAILURE(rv)) 708 if (ACPI_FAILURE(rv))
709 return rv; 709 return rv;
710 710
711 props = NULL; 711 props = NULL;
712 obj = (ACPI_OBJECT *)pbuf->Pointer; 712 obj = (ACPI_OBJECT *)pbuf->Pointer;
713 for (n = 0; (n + 1) < obj->Package.Count; n += 2) { 713 for (n = 0; (n + 1) < obj->Package.Count; n += 2) {
714 uuid = &obj->Package.Elements[n]; 714 uuid = &obj->Package.Elements[n];
715 if (uuid->Buffer.Length == ACPI_UUID_LENGTH && 715 if (uuid->Buffer.Length == ACPI_UUID_LENGTH &&
716 memcmp(uuid->Buffer.Pointer, acpi_dsd_uuid, ACPI_UUID_LENGTH) == 0) { 716 memcmp(uuid->Buffer.Pointer, acpi_dsd_uuid, ACPI_UUID_LENGTH) == 0) {
717 props = &obj->Package.Elements[n + 1]; 717 props = &obj->Package.Elements[n + 1];
718 break; 718 break;
719 } 719 }
720 } 720 }
721 if (props == NULL) 721 if (props == NULL)
722 return AE_NOT_FOUND; 722 return AE_NOT_FOUND;
723 723
724 for (n = 0; n < props->Package.Count; n++) { 724 for (n = 0; n < props->Package.Count; n++) {
725 pobj = &props->Package.Elements[n]; 725 pobj = &props->Package.Elements[n];
726 if (pobj->Type != ACPI_TYPE_PACKAGE || pobj->Package.Count != 2) 726 if (pobj->Type != ACPI_TYPE_PACKAGE || pobj->Package.Count != 2)
727 continue; 727 continue;
728 propkey = (ACPI_OBJECT *)&pobj->Package.Elements[0]; 728 propkey = (ACPI_OBJECT *)&pobj->Package.Elements[0];
729 propval = (ACPI_OBJECT *)&pobj->Package.Elements[1]; 729 propval = (ACPI_OBJECT *)&pobj->Package.Elements[1];
730 if (propkey->Type != ACPI_TYPE_STRING) 730 if (propkey->Type != ACPI_TYPE_STRING)
731 continue; 731 continue;
732 if (strcmp(propkey->String.Pointer, prop) != 0) 732 if (strcmp(propkey->String.Pointer, prop) != 0)
733 continue; 733 continue;
734 734
735 if (propval->Type != type) { 735 if (propval->Type != type) {
736 return AE_TYPE; 736 return AE_TYPE;
737 } else { 737 } else {
738 *ret = propval; 738 *ret = propval;
739 return AE_OK; 739 return AE_OK;
740 } 740 }
741 break; 741 break;
742 } 742 }
743 743
744 return AE_NOT_FOUND; 744 return AE_NOT_FOUND;
745} 745}
746 746
747ACPI_STATUS 747ACPI_STATUS
748acpi_dsd_integer(ACPI_HANDLE handle, const char *prop, ACPI_INTEGER *val) 748acpi_dsd_integer(ACPI_HANDLE handle, const char *prop, ACPI_INTEGER *val)
749{ 749{
750 ACPI_OBJECT *propval; 750 ACPI_OBJECT *propval;
751 ACPI_STATUS rv; 751 ACPI_STATUS rv;
752 ACPI_BUFFER buf; 752 ACPI_BUFFER buf;
753 753
754 buf.Pointer = NULL; 754 buf.Pointer = NULL;
755 buf.Length = ACPI_ALLOCATE_BUFFER; 755 buf.Length = ACPI_ALLOCATE_BUFFER;
756 756
757 rv = acpi_dsd_property(handle, prop, &buf, ACPI_TYPE_INTEGER, &propval); 757 rv = acpi_dsd_property(handle, prop, &buf, ACPI_TYPE_INTEGER, &propval);
758 if (ACPI_SUCCESS(rv)) 758 if (ACPI_SUCCESS(rv))
759 *val = propval->Integer.Value; 759 *val = propval->Integer.Value;
760 760
761 if (buf.Pointer != NULL) 761 if (buf.Pointer != NULL)
762 ACPI_FREE(buf.Pointer); 762 ACPI_FREE(buf.Pointer);
763 return rv; 763 return rv;
764} 764}
765 765
766ACPI_STATUS 766ACPI_STATUS
767acpi_dsd_string(ACPI_HANDLE handle, const char *prop, char **val) 767acpi_dsd_string(ACPI_HANDLE handle, const char *prop, char **val)
768{ 768{
769 ACPI_OBJECT *propval; 769 ACPI_OBJECT *propval;
770 ACPI_STATUS rv; 770 ACPI_STATUS rv;
771 ACPI_BUFFER buf; 771 ACPI_BUFFER buf;
772 772
773 buf.Pointer = NULL; 773 buf.Pointer = NULL;
774 buf.Length = ACPI_ALLOCATE_BUFFER; 774 buf.Length = ACPI_ALLOCATE_BUFFER;
775 775
776 rv = acpi_dsd_property(handle, prop, &buf, ACPI_TYPE_STRING, &propval); 776 rv = acpi_dsd_property(handle, prop, &buf, ACPI_TYPE_STRING, &propval);
777 if (ACPI_SUCCESS(rv)) 777 if (ACPI_SUCCESS(rv))
778 *val = kmem_strdup(propval->String.Pointer, KM_SLEEP); 778 *val = kmem_strdup(propval->String.Pointer, KM_SLEEP);
779 779
780 if (buf.Pointer != NULL) 780 if (buf.Pointer != NULL)
781 ACPI_FREE(buf.Pointer); 781 ACPI_FREE(buf.Pointer);
782 return rv; 782 return rv;
783} 783}
784 784
785/* 785/*
786 * Device Specific Method (_DSM) support 786 * Device Specific Method (_DSM) support
787 */ 787 */
788 788
789ACPI_STATUS 789ACPI_STATUS
790acpi_dsm_typed(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev, 790acpi_dsm_typed(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev,
791 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_OBJECT_TYPE return_type, 791 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_OBJECT_TYPE return_type,
792 ACPI_OBJECT **return_obj) 792 ACPI_OBJECT **return_obj)
793{ 793{
794 ACPI_OBJECT_LIST arg; 794 ACPI_OBJECT_LIST arg;
795 ACPI_OBJECT obj[4]; 795 ACPI_OBJECT obj[4];
796 ACPI_BUFFER buf; 796 ACPI_BUFFER buf;
797 ACPI_STATUS status; 797 ACPI_STATUS status;
798 798
799 arg.Count = 4; 799 arg.Count = 4;
800 arg.Pointer = obj; 800 arg.Pointer = obj;
801 801
802 obj[0].Type = ACPI_TYPE_BUFFER; 802 obj[0].Type = ACPI_TYPE_BUFFER;
803 obj[0].Buffer.Length = ACPI_UUID_LENGTH; 803 obj[0].Buffer.Length = ACPI_UUID_LENGTH;
804 obj[0].Buffer.Pointer = uuid; 804 obj[0].Buffer.Pointer = uuid;
805 805
806 obj[1].Type = ACPI_TYPE_INTEGER; 806 obj[1].Type = ACPI_TYPE_INTEGER;
807 obj[1].Integer.Value = rev; 807 obj[1].Integer.Value = rev;
808 808
809 obj[2].Type = ACPI_TYPE_INTEGER; 809 obj[2].Type = ACPI_TYPE_INTEGER;
810 obj[2].Integer.Value = func; 810 obj[2].Integer.Value = func;
811 811
812 if (arg3 != NULL) { 812 if (arg3 != NULL) {
813 obj[3] = *arg3; 813 obj[3] = *arg3;
814 } else { 814 } else {
815 obj[3].Type = ACPI_TYPE_PACKAGE; 815 obj[3].Type = ACPI_TYPE_PACKAGE;
816 obj[3].Package.Count = 0; 816 obj[3].Package.Count = 0;
817 obj[3].Package.Elements = NULL; 817 obj[3].Package.Elements = NULL;
818 } 818 }
819 819
820 buf.Pointer = NULL; 820 buf.Pointer = NULL;
821 buf.Length = ACPI_ALLOCATE_BUFFER; 821 buf.Length = ACPI_ALLOCATE_BUFFER;
822 822
823 if (return_obj == NULL && return_type == ACPI_TYPE_ANY) { 823 if (return_obj == NULL && return_type == ACPI_TYPE_ANY) {
824 status = AcpiEvaluateObject(handle, "_DSM", &arg, NULL); 824 status = AcpiEvaluateObject(handle, "_DSM", &arg, NULL);
825 } else { 825 } else {
826 *return_obj = NULL; 826 *return_obj = NULL;
827 status = AcpiEvaluateObjectTyped(handle, "_DSM", &arg, &buf, 827 status = AcpiEvaluateObjectTyped(handle, "_DSM", &arg, &buf,
828 return_type); 828 return_type);
829 } 829 }
830 if (ACPI_FAILURE(status)) { 830 if (ACPI_FAILURE(status)) {
831 return status; 831 return status;
832 } 832 }
833 if (return_obj != NULL) { 833 if (return_obj != NULL) {
834 *return_obj = buf.Pointer; 834 *return_obj = buf.Pointer;
835 } else if (buf.Pointer != NULL) { 835 } else if (buf.Pointer != NULL) {
836 ACPI_FREE(buf.Pointer); 836 ACPI_FREE(buf.Pointer);
837 } 837 }
838 return AE_OK; 838 return AE_OK;
839} 839}
840 840
841ACPI_STATUS 841ACPI_STATUS
842acpi_dsm_integer(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev, 842acpi_dsm_integer(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev,
843 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_INTEGER *ret) 843 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_INTEGER *ret)
844{ 844{
845 ACPI_OBJECT *obj; 845 ACPI_OBJECT *obj;
846 ACPI_STATUS status; 846 ACPI_STATUS status;
847 847
848 status = acpi_dsm_typed(handle, uuid, rev, func, arg3, 848 status = acpi_dsm_typed(handle, uuid, rev, func, arg3,
849 ACPI_TYPE_INTEGER, &obj); 849 ACPI_TYPE_INTEGER, &obj);
850 if (ACPI_FAILURE(status)) { 850 if (ACPI_FAILURE(status)) {
851 return status; 851 return status;
852 } 852 }
853 853
854 *ret = obj->Integer.Value; 854 *ret = obj->Integer.Value;
855 ACPI_FREE(obj); 855 ACPI_FREE(obj);
856 856
857 return AE_OK; 857 return AE_OK;
858} 858}
859 859
860ACPI_STATUS 860ACPI_STATUS
861acpi_dsm(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev, 861acpi_dsm(ACPI_HANDLE handle, uint8_t *uuid, ACPI_INTEGER rev,
862 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_OBJECT **return_obj) 862 ACPI_INTEGER func, const ACPI_OBJECT *arg3, ACPI_OBJECT **return_obj)
863{ 863{
864 return acpi_dsm_typed(handle, uuid, rev, func, arg3, ACPI_TYPE_ANY, 864 return acpi_dsm_typed(handle, uuid, rev, func, arg3, ACPI_TYPE_ANY,
865 return_obj); 865 return_obj);
866} 866}
 867
 868ACPI_STATUS
 869acpi_claim_childdevs(device_t dev, struct acpi_devnode *devnode)
 870{
 871 struct acpi_devnode *ad;
 872
 873 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
 874 if (ad->ad_device != NULL)
 875 continue;
 876 aprint_debug(dev, "claiming %s\n", acpi_name(ad->ad_handle));
 877 ad->ad_device = dev;
 878 acpi_claim_childdevs(dev, ad);
 879 }
 880
 881 return AE_OK;
 882}

cvs diff -r1.5 -r1.6 src/sys/dev/acpi/dwiic_acpi.c (switch to unified diff)

--- src/sys/dev/acpi/dwiic_acpi.c 2021/01/24 16:33:48 1.5
+++ src/sys/dev/acpi/dwiic_acpi.c 2021/01/26 00:19:53 1.6
@@ -1,182 +1,182 @@ @@ -1,182 +1,182 @@
1/* $NetBSD: dwiic_acpi.c,v 1.5 2021/01/24 16:33:48 jmcneill Exp $ */ 1/* $NetBSD: dwiic_acpi.c,v 1.6 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: dwiic_acpi.c,v 1.5 2021/01/24 16:33:48 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: dwiic_acpi.c,v 1.6 2021/01/26 00:19:53 jmcneill Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/bus.h> 36#include <sys/bus.h>
37#include <sys/cpu.h> 37#include <sys/cpu.h>
38#include <sys/device.h> 38#include <sys/device.h>
39 39
40#include <dev/acpi/acpireg.h> 40#include <dev/acpi/acpireg.h>
41#include <dev/acpi/acpivar.h> 41#include <dev/acpi/acpivar.h>
42#include <dev/acpi/acpi_intr.h> 42#include <dev/acpi/acpi_intr.h>
43#include <dev/acpi/acpi_i2c.h> 43#include <dev/acpi/acpi_i2c.h>
44 44
45#include <dev/ic/dwiic_var.h> 45#include <dev/ic/dwiic_var.h>
46 46
47struct dwiic_acpi_param { 47struct dwiic_acpi_param {
48 uint16_t hcnt; 48 uint16_t hcnt;
49 uint16_t lcnt; 49 uint16_t lcnt;
50 uint32_t ht; 50 uint32_t ht;
51}; 51};
52 52
53static int dwiic_acpi_match(device_t, cfdata_t, void *); 53static int dwiic_acpi_match(device_t, cfdata_t, void *);
54static void dwiic_acpi_attach(device_t, device_t, void *); 54static void dwiic_acpi_attach(device_t, device_t, void *);
55 55
56static void dwiic_acpi_parse_param(struct dwiic_softc *, ACPI_HANDLE, 56static void dwiic_acpi_parse_param(struct dwiic_softc *, ACPI_HANDLE,
57 const char *, struct dwiic_acpi_param *); 57 const char *, struct dwiic_acpi_param *);
58static void dwiic_acpi_configure(struct dwiic_softc *, ACPI_HANDLE); 58static void dwiic_acpi_configure(struct dwiic_softc *, ACPI_HANDLE);
59 59
60CFATTACH_DECL_NEW(dwiic_acpi, sizeof(struct dwiic_softc), dwiic_acpi_match, dwiic_acpi_attach, NULL, NULL); 60CFATTACH_DECL_NEW(dwiic_acpi, sizeof(struct dwiic_softc), dwiic_acpi_match, dwiic_acpi_attach, NULL, NULL);
61 61
62static const char * const compatible[] = { 62static const char * const compatible[] = {
63 "AMD0010", /* AMD FCH */ 63 "AMD0010", /* AMD FCH */
64 "AMDI0010", /* AMD FCH */ 64 "AMDI0010", /* AMD FCH */
65 "AMDI0510", /* AMD Seattle */ 65 "AMDI0510", /* AMD Seattle */
66 "APMC0D0F", /* Ampere eMAG */ 66 "APMC0D0F", /* Ampere eMAG */
67 NULL 67 NULL
68}; 68};
69 69
70static int 70static int
71dwiic_acpi_match(device_t parent, cfdata_t cf, void *aux) 71dwiic_acpi_match(device_t parent, cfdata_t cf, void *aux)
72{ 72{
73 struct acpi_attach_args *aa = aux; 73 struct acpi_attach_args *aa = aux;
74 74
75 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) 75 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
76 return 0; 76 return 0;
77 77
78 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible); 78 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
79} 79}
80 80
81static void 81static void
82dwiic_acpi_attach(device_t parent, device_t self, void *aux) 82dwiic_acpi_attach(device_t parent, device_t self, void *aux)
83{ 83{
84 struct dwiic_softc * const sc = device_private(self); 84 struct dwiic_softc * const sc = device_private(self);
85 struct acpi_attach_args *aa = aux; 85 struct acpi_attach_args *aa = aux;
86 struct acpi_resources res; 86 struct acpi_resources res;
87 struct acpi_mem *mem; 87 struct acpi_mem *mem;
88 struct acpi_irq *irq; 88 struct acpi_irq *irq;
89 ACPI_STATUS rv; 89 ACPI_STATUS rv;
90 int error; 90 int error;
91 void *ih; 91 void *ih;
92 92
93 sc->sc_dev = self; 93 sc->sc_dev = self;
94 sc->sc_type = dwiic_type_generic; 94 sc->sc_type = dwiic_type_generic;
95 sc->sc_iot = aa->aa_memt; 95 sc->sc_iot = aa->aa_memt;
96 96
97 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS", 97 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS",
98 &res, &acpi_resource_parse_ops_default); 98 &res, &acpi_resource_parse_ops_default);
99 if (ACPI_FAILURE(rv)) 99 if (ACPI_FAILURE(rv))
100 return; 100 return;
101 101
102 mem = acpi_res_mem(&res, 0); 102 mem = acpi_res_mem(&res, 0);
103 if (mem == NULL) { 103 if (mem == NULL) {
104 aprint_error_dev(self, "couldn't find mem resource\n"); 104 aprint_error_dev(self, "couldn't find mem resource\n");
105 goto done; 105 goto done;
106 } 106 }
107 107
108 irq = acpi_res_irq(&res, 0); 108 irq = acpi_res_irq(&res, 0);
109 if (irq == NULL) { 109 if (irq == NULL) {
110 aprint_error_dev(self, "couldn't find irq resource\n"); 110 aprint_error_dev(self, "couldn't find irq resource\n");
111 goto done; 111 goto done;
112 } 112 }
113 113
114 error = bus_space_map(sc->sc_iot, mem->ar_base, mem->ar_length, 0, &sc->sc_ioh); 114 error = bus_space_map(sc->sc_iot, mem->ar_base, mem->ar_length, 0, &sc->sc_ioh);
115 if (error) { 115 if (error) {
116 aprint_error_dev(self, "couldn't map registers\n"); 116 aprint_error_dev(self, "couldn't map registers\n");
117 return; 117 return;
118 } 118 }
119 119
120 ih = acpi_intr_establish(self, 120 ih = acpi_intr_establish(self,
121 (uint64_t)(uintptr_t)aa->aa_node->ad_handle, 121 (uint64_t)(uintptr_t)aa->aa_node->ad_handle,
122 IPL_VM, true, dwiic_intr, sc, device_xname(self)); 122 IPL_VM, true, dwiic_intr, sc, device_xname(self));
123 if (ih == NULL) { 123 if (ih == NULL) {
124 aprint_error_dev(self, "couldn't install interrupt handler\n"); 124 aprint_error_dev(self, "couldn't install interrupt handler\n");
125 bus_space_unmap(sc->sc_iot, sc->sc_ioh, mem->ar_length); 125 bus_space_unmap(sc->sc_iot, sc->sc_ioh, mem->ar_length);
126 goto done; 126 goto done;
127 } 127 }
128 128
129 dwiic_acpi_configure(sc, aa->aa_node->ad_handle); 129 dwiic_acpi_configure(sc, aa->aa_node->ad_handle);
130 130
131 sc->sc_iba.iba_child_devices = acpi_enter_i2c_devs(aa->aa_node); 131 sc->sc_iba.iba_child_devices = acpi_enter_i2c_devs(self, aa->aa_node);
132 132
133 dwiic_attach(sc); 133 dwiic_attach(sc);
134 134
135 config_found_ia(self, "i2cbus", &sc->sc_iba, iicbus_print); 135 config_found_ia(self, "i2cbus", &sc->sc_iba, iicbus_print);
136 136
137 pmf_device_register(self, dwiic_suspend, dwiic_resume); 137 pmf_device_register(self, dwiic_suspend, dwiic_resume);
138 138
139done: 139done:
140 acpi_resource_cleanup(&res); 140 acpi_resource_cleanup(&res);
141} 141}
142 142
143static void 143static void
144dwiic_acpi_parse_param(struct dwiic_softc *sc, ACPI_HANDLE handle, const char *path, 144dwiic_acpi_parse_param(struct dwiic_softc *sc, ACPI_HANDLE handle, const char *path,
145 struct dwiic_acpi_param *param) 145 struct dwiic_acpi_param *param)
146{ 146{
147 ACPI_BUFFER buf; 147 ACPI_BUFFER buf;
148 ACPI_OBJECT *obj; 148 ACPI_OBJECT *obj;
149 149
150 memset(param, 0, sizeof(*param)); 150 memset(param, 0, sizeof(*param));
151 151
152 if (ACPI_FAILURE(acpi_eval_struct(handle, path, &buf))) 152 if (ACPI_FAILURE(acpi_eval_struct(handle, path, &buf)))
153 return; 153 return;
154 154
155 obj = buf.Pointer; 155 obj = buf.Pointer;
156 if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count != 3) 156 if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count != 3)
157 goto done; 157 goto done;
158 158
159 param->hcnt = (uint16_t)obj->Package.Elements[0].Integer.Value; 159 param->hcnt = (uint16_t)obj->Package.Elements[0].Integer.Value;
160 param->lcnt = (uint16_t)obj->Package.Elements[1].Integer.Value; 160 param->lcnt = (uint16_t)obj->Package.Elements[1].Integer.Value;
161 param->ht = (uint32_t)obj->Package.Elements[2].Integer.Value; 161 param->ht = (uint32_t)obj->Package.Elements[2].Integer.Value;
162 162
163done: 163done:
164 ACPI_FREE(buf.Pointer); 164 ACPI_FREE(buf.Pointer);
165} 165}
166 166
167static void 167static void
168dwiic_acpi_configure(struct dwiic_softc *sc, ACPI_HANDLE handle) 168dwiic_acpi_configure(struct dwiic_softc *sc, ACPI_HANDLE handle)
169{ 169{
170 struct dwiic_acpi_param sscn, fmcn; 170 struct dwiic_acpi_param sscn, fmcn;
171 171
172 dwiic_acpi_parse_param(sc, handle, "SSCN", &sscn); 172 dwiic_acpi_parse_param(sc, handle, "SSCN", &sscn);
173 sc->ss_hcnt = sscn.hcnt; 173 sc->ss_hcnt = sscn.hcnt;
174 sc->ss_lcnt = sscn.lcnt; 174 sc->ss_lcnt = sscn.lcnt;
175 175
176 dwiic_acpi_parse_param(sc, handle, "FMCN", &fmcn); 176 dwiic_acpi_parse_param(sc, handle, "FMCN", &fmcn);
177 sc->fs_hcnt = fmcn.hcnt; 177 sc->fs_hcnt = fmcn.hcnt;
178 sc->fs_lcnt = fmcn.lcnt; 178 sc->fs_lcnt = fmcn.lcnt;
179 179
180 /* XXX */ 180 /* XXX */
181 sc->sda_hold_time = fmcn.ht; 181 sc->sda_hold_time = fmcn.ht;
182} 182}

cvs diff -r1.2 -r1.3 src/sys/dev/acpi/nxpiic_acpi.c (switch to unified diff)

--- src/sys/dev/acpi/nxpiic_acpi.c 2021/01/25 12:09:58 1.2
+++ src/sys/dev/acpi/nxpiic_acpi.c 2021/01/26 00:19:53 1.3
@@ -1,183 +1,183 @@ @@ -1,183 +1,183 @@
1/* $NetBSD: nxpiic_acpi.c,v 1.2 2021/01/25 12:09:58 jmcneill Exp $ */ 1/* $NetBSD: nxpiic_acpi.c,v 1.3 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2021 The NetBSD Foundation, Inc. 4 * Copyright (c) 2021 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: nxpiic_acpi.c,v 1.2 2021/01/25 12:09:58 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: nxpiic_acpi.c,v 1.3 2021/01/26 00:19:53 jmcneill Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/bus.h> 36#include <sys/bus.h>
37#include <sys/cpu.h> 37#include <sys/cpu.h>
38#include <sys/device.h> 38#include <sys/device.h>
39 39
40#include <dev/acpi/acpireg.h> 40#include <dev/acpi/acpireg.h>
41#include <dev/acpi/acpivar.h> 41#include <dev/acpi/acpivar.h>
42#include <dev/acpi/acpi_intr.h> 42#include <dev/acpi/acpi_intr.h>
43#include <dev/acpi/acpi_i2c.h> 43#include <dev/acpi/acpi_i2c.h>
44 44
45#include <dev/i2c/motoi2cvar.h> 45#include <dev/i2c/motoi2cvar.h>
46#include <dev/i2c/motoi2creg.h> 46#include <dev/i2c/motoi2creg.h>
47 47
48#define NXPIIC_SPEED_STD 100000 48#define NXPIIC_SPEED_STD 100000
49 49
50static const struct clk_div { 50static const struct clk_div {
51 int scl_div; 51 int scl_div;
52 uint8_t ibc; 52 uint8_t ibc;
53} nxpiic_clk_div[] = { 53} nxpiic_clk_div[] = {
54 { 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 }, 54 { 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 },
55 { 28, 0x04 }, { 30, 0x05 }, { 32, 0x09 }, { 34, 0x06 }, 55 { 28, 0x04 }, { 30, 0x05 }, { 32, 0x09 }, { 34, 0x06 },
56 { 36, 0x0a }, { 40, 0x07 }, { 44, 0x0c }, { 48, 0x0d }, 56 { 36, 0x0a }, { 40, 0x07 }, { 44, 0x0c }, { 48, 0x0d },
57 { 52, 0x43 }, { 56, 0x0e }, { 60, 0x45 }, { 64, 0x12 }, 57 { 52, 0x43 }, { 56, 0x0e }, { 60, 0x45 }, { 64, 0x12 },
58 { 68, 0x0f }, { 72, 0x13 }, { 80, 0x14 }, { 88, 0x15 }, 58 { 68, 0x0f }, { 72, 0x13 }, { 80, 0x14 }, { 88, 0x15 },
59 { 96, 0x19 }, { 104, 0x16 }, { 112, 0x1a }, { 128, 0x17 }, 59 { 96, 0x19 }, { 104, 0x16 }, { 112, 0x1a }, { 128, 0x17 },
60 { 136, 0x4f }, { 144, 0x1c }, { 160, 0x1d }, { 176, 0x55 }, 60 { 136, 0x4f }, { 144, 0x1c }, { 160, 0x1d }, { 176, 0x55 },
61 { 192, 0x1e }, { 208, 0x56 }, { 224, 0x22 }, { 228, 0x24 }, 61 { 192, 0x1e }, { 208, 0x56 }, { 224, 0x22 }, { 228, 0x24 },
62 { 240, 0x1f }, { 256, 0x23 }, { 288, 0x5c }, { 320, 0x25 }, 62 { 240, 0x1f }, { 256, 0x23 }, { 288, 0x5c }, { 320, 0x25 },
63 { 384, 0x26 }, { 448, 0x2a }, { 480, 0x27 }, { 512, 0x2b }, 63 { 384, 0x26 }, { 448, 0x2a }, { 480, 0x27 }, { 512, 0x2b },
64 { 576, 0x2c }, { 640, 0x2d }, { 768, 0x31 }, { 896, 0x32 }, 64 { 576, 0x2c }, { 640, 0x2d }, { 768, 0x31 }, { 896, 0x32 },
65 { 960, 0x2f }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 }, 65 { 960, 0x2f }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 },
66 { 1536, 0x36 }, { 1792, 0x3a }, { 1920, 0x37 }, { 2048, 0x3b }, 66 { 1536, 0x36 }, { 1792, 0x3a }, { 1920, 0x37 }, { 2048, 0x3b },
67 { 2304, 0x3c }, { 2560, 0x3d }, { 3072, 0x3e }, { 3584, 0x7a }, 67 { 2304, 0x3c }, { 2560, 0x3d }, { 3072, 0x3e }, { 3584, 0x7a },
68 { 3840, 0x3f }, { 4096, 0x7B }, { 5120, 0x7d }, { 6144, 0x7e }, 68 { 3840, 0x3f }, { 4096, 0x7B }, { 5120, 0x7d }, { 6144, 0x7e },
69}; 69};
70 70
71struct nxpiic_softc { 71struct nxpiic_softc {
72 device_t sc_dev; 72 device_t sc_dev;
73 struct motoi2c_softc sc_motoi2c; 73 struct motoi2c_softc sc_motoi2c;
74}; 74};
75 75
76static int nxpiic_acpi_match(device_t, cfdata_t, void *); 76static int nxpiic_acpi_match(device_t, cfdata_t, void *);
77static void nxpiic_acpi_attach(device_t, device_t, void *); 77static void nxpiic_acpi_attach(device_t, device_t, void *);
78 78
79static uint8_t nxpiic_acpi_iord(struct motoi2c_softc *, bus_size_t); 79static uint8_t nxpiic_acpi_iord(struct motoi2c_softc *, bus_size_t);
80static void nxpiic_acpi_iowr(struct motoi2c_softc *, bus_size_t, uint8_t); 80static void nxpiic_acpi_iowr(struct motoi2c_softc *, bus_size_t, uint8_t);
81 81
82CFATTACH_DECL_NEW(nxpiic_acpi, sizeof(struct nxpiic_softc), 82CFATTACH_DECL_NEW(nxpiic_acpi, sizeof(struct nxpiic_softc),
83 nxpiic_acpi_match, nxpiic_acpi_attach, NULL, NULL); 83 nxpiic_acpi_match, nxpiic_acpi_attach, NULL, NULL);
84 84
85static const char * const compatible[] = { 85static const char * const compatible[] = {
86 "NXP0001", 86 "NXP0001",
87 NULL 87 NULL
88}; 88};
89 89
90static int 90static int
91nxpiic_acpi_match(device_t parent, cfdata_t cf, void *aux) 91nxpiic_acpi_match(device_t parent, cfdata_t cf, void *aux)
92{ 92{
93 struct acpi_attach_args *aa = aux; 93 struct acpi_attach_args *aa = aux;
94 94
95 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) 95 if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
96 return 0; 96 return 0;
97 97
98 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible); 98 return acpi_match_hid(aa->aa_node->ad_devinfo, compatible);
99} 99}
100 100
101static void 101static void
102nxpiic_acpi_attach(device_t parent, device_t self, void *aux) 102nxpiic_acpi_attach(device_t parent, device_t self, void *aux)
103{ 103{
104 struct nxpiic_softc * const sc = device_private(self); 104 struct nxpiic_softc * const sc = device_private(self);
105 struct motoi2c_softc * const msc = &sc->sc_motoi2c; 105 struct motoi2c_softc * const msc = &sc->sc_motoi2c;
106 struct motoi2c_settings settings; 106 struct motoi2c_settings settings;
107 struct acpi_attach_args *aa = aux; 107 struct acpi_attach_args *aa = aux;
108 struct acpi_resources res; 108 struct acpi_resources res;
109 struct acpi_mem *mem; 109 struct acpi_mem *mem;
110 ACPI_INTEGER clock_freq; 110 ACPI_INTEGER clock_freq;
111 ACPI_STATUS rv; 111 ACPI_STATUS rv;
112 int error, n; 112 int error, n;
113 113
114 sc->sc_dev = self; 114 sc->sc_dev = self;
115 msc->sc_iot = aa->aa_memt; 115 msc->sc_iot = aa->aa_memt;
116 116
117 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS", 117 rv = acpi_resource_parse(sc->sc_dev, aa->aa_node->ad_handle, "_CRS",
118 &res, &acpi_resource_parse_ops_default); 118 &res, &acpi_resource_parse_ops_default);
119 if (ACPI_FAILURE(rv)) 119 if (ACPI_FAILURE(rv))
120 return; 120 return;
121 121
122 mem = acpi_res_mem(&res, 0); 122 mem = acpi_res_mem(&res, 0);
123 if (mem == NULL) { 123 if (mem == NULL) {
124 aprint_error_dev(self, "couldn't find mem resource\n"); 124 aprint_error_dev(self, "couldn't find mem resource\n");
125 goto done; 125 goto done;
126 } 126 }
127 127
128 rv = acpi_dsd_integer(aa->aa_node->ad_handle, "clock-frequency", 128 rv = acpi_dsd_integer(aa->aa_node->ad_handle, "clock-frequency",
129 &clock_freq); 129 &clock_freq);
130 if (ACPI_FAILURE(rv) || clock_freq == 0) { 130 if (ACPI_FAILURE(rv) || clock_freq == 0) {
131 aprint_error_dev(self, "couldn't get clock frequency\n"); 131 aprint_error_dev(self, "couldn't get clock frequency\n");
132 goto done; 132 goto done;
133 } 133 }
134 aprint_debug_dev(self, "bus clock %u Hz\n", (u_int)clock_freq); 134 aprint_debug_dev(self, "bus clock %u Hz\n", (u_int)clock_freq);
135 135
136 error = bus_space_map(msc->sc_iot, mem->ar_base, mem->ar_length, 0, 136 error = bus_space_map(msc->sc_iot, mem->ar_base, mem->ar_length, 0,
137 &msc->sc_ioh); 137 &msc->sc_ioh);
138 if (error) { 138 if (error) {
139 aprint_error_dev(self, "couldn't map registers\n"); 139 aprint_error_dev(self, "couldn't map registers\n");
140 return; 140 return;
141 } 141 }
142 142
143 settings.i2c_adr = MOTOI2C_ADR_DEFAULT; 143 settings.i2c_adr = MOTOI2C_ADR_DEFAULT;
144 settings.i2c_dfsrr = MOTOI2C_DFSRR_DEFAULT; 144 settings.i2c_dfsrr = MOTOI2C_DFSRR_DEFAULT;
145 for (n = 0; n < __arraycount(nxpiic_clk_div) - 1; n++) { 145 for (n = 0; n < __arraycount(nxpiic_clk_div) - 1; n++) {
146 if (clock_freq / nxpiic_clk_div[n].scl_div < NXPIIC_SPEED_STD) 146 if (clock_freq / nxpiic_clk_div[n].scl_div < NXPIIC_SPEED_STD)
147 break; 147 break;
148 } 148 }
149 settings.i2c_fdr = nxpiic_clk_div[n].ibc; 149 settings.i2c_fdr = nxpiic_clk_div[n].ibc;
150 150
151 msc->sc_flags |= MOTOI2C_F_ENABLE_INV | MOTOI2C_F_STATUS_W1C; 151 msc->sc_flags |= MOTOI2C_F_ENABLE_INV | MOTOI2C_F_STATUS_W1C;
152 msc->sc_iord = nxpiic_acpi_iord; 152 msc->sc_iord = nxpiic_acpi_iord;
153 msc->sc_iowr = nxpiic_acpi_iowr; 153 msc->sc_iowr = nxpiic_acpi_iowr;
154 msc->sc_child_devices = acpi_enter_i2c_devs(aa->aa_node); 154 msc->sc_child_devices = acpi_enter_i2c_devs(self, aa->aa_node);
155 155
156 motoi2c_attach_common(self, msc, &settings); 156 motoi2c_attach_common(self, msc, &settings);
157 157
158done: 158done:
159 acpi_resource_cleanup(&res); 159 acpi_resource_cleanup(&res);
160 160
161} 161}
162 162
163static uint8_t 163static uint8_t
164nxpiic_acpi_iord(struct motoi2c_softc *msc, bus_size_t off) 164nxpiic_acpi_iord(struct motoi2c_softc *msc, bus_size_t off)
165{ 165{
166 KASSERT((off & 3) == 0); 166 KASSERT((off & 3) == 0);
167 167
168 if (off >= I2CDFSRR) 168 if (off >= I2CDFSRR)
169 return 0; 169 return 0;
170 170
171 return bus_space_read_1(msc->sc_iot, msc->sc_ioh, off >> 2); 171 return bus_space_read_1(msc->sc_iot, msc->sc_ioh, off >> 2);
172} 172}
173 173
174static void 174static void
175nxpiic_acpi_iowr(struct motoi2c_softc *msc, bus_size_t off, uint8_t val) 175nxpiic_acpi_iowr(struct motoi2c_softc *msc, bus_size_t off, uint8_t val)
176{ 176{
177 KASSERT((off & 3) == 0); 177 KASSERT((off & 3) == 0);
178 178
179 if (off >= I2CDFSRR) 179 if (off >= I2CDFSRR)
180 return; 180 return;
181 181
182 bus_space_write_1(msc->sc_iot, msc->sc_ioh, off >> 2, val); 182 bus_space_write_1(msc->sc_iot, msc->sc_ioh, off >> 2, val);
183} 183}

cvs diff -r1.3 -r1.4 src/sys/dev/i2c/i2cmux.c (switch to unified diff)

--- src/sys/dev/i2c/i2cmux.c 2021/01/25 12:18:18 1.3
+++ src/sys/dev/i2c/i2cmux.c 2021/01/26 00:19:53 1.4
@@ -1,316 +1,316 @@ @@ -1,316 +1,316 @@
1/* $NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $ */ 1/* $NetBSD: i2cmux.c,v 1.4 2021/01/26 00:19:53 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe. 8 * by Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) 32#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
33#include "acpica.h" 33#include "acpica.h"
34#endif 34#endif
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.4 2021/01/26 00:19:53 jmcneill Exp $");
38 38
39#include <sys/types.h> 39#include <sys/types.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/kernel.h> 41#include <sys/kernel.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43 43
44#include <dev/fdt/fdtvar.h> 44#include <dev/fdt/fdtvar.h>
45#include <dev/i2c/i2cvar.h> 45#include <dev/i2c/i2cvar.h>
46#include <dev/i2c/i2cmuxvar.h> 46#include <dev/i2c/i2cmuxvar.h>
47 47
48#if NACPICA > 0 48#if NACPICA > 0
49#include <dev/acpi/acpivar.h> 49#include <dev/acpi/acpivar.h>
50#include <dev/acpi/acpi_i2c.h> 50#include <dev/acpi/acpi_i2c.h>
51#endif 51#endif
52 52
53/* 53/*
54 * i2c mux 54 * i2c mux
55 * 55 *
56 * This works by interposing a set of virtual controllers behind the real 56 * This works by interposing a set of virtual controllers behind the real
57 * i2c controller. We provide our own acquire and release functions that 57 * i2c controller. We provide our own acquire and release functions that
58 * perform the following tasks: 58 * perform the following tasks:
59 * 59 *
60 * acquire -> acquire parent controller, program mux 60 * acquire -> acquire parent controller, program mux
61 * 61 *
62 * release -> idle mux, release parent controller 62 * release -> idle mux, release parent controller
63 * 63 *
64 * All of the actual I/O operations are transparently passed through. 64 * All of the actual I/O operations are transparently passed through.
65 * 65 *
66 * N.B. the locking order; the generic I2C layer has already acquired 66 * N.B. the locking order; the generic I2C layer has already acquired
67 * our virtual controller's mutex before calling our acquire function, 67 * our virtual controller's mutex before calling our acquire function,
68 * and we will then acquire the real controller's mutex when we acquire 68 * and we will then acquire the real controller's mutex when we acquire
69 * the bus, so the order is: 69 * the bus, so the order is:
70 * 70 *
71 * mux virtual controller -> parent controller 71 * mux virtual controller -> parent controller
72 * 72 *
73 * These are common routines used by various i2c mux controller 73 * These are common routines used by various i2c mux controller
74 * implementations (gpio, pin mux, i2c device, etc.). 74 * implementations (gpio, pin mux, i2c device, etc.).
75 */ 75 */
76 76
77/*****************************************************************************/ 77/*****************************************************************************/
78 78
79static int 79static int
80iicmux_acquire_bus(void * const v, int const flags) 80iicmux_acquire_bus(void * const v, int const flags)
81{ 81{
82 struct iicmux_bus * const bus = v; 82 struct iicmux_bus * const bus = v;
83 struct iicmux_softc * const sc = bus->mux; 83 struct iicmux_softc * const sc = bus->mux;
84 int error; 84 int error;
85 85
86 error = iic_acquire_bus(sc->sc_i2c_parent, flags); 86 error = iic_acquire_bus(sc->sc_i2c_parent, flags);
87 if (error) { 87 if (error) {
88 return error; 88 return error;
89 } 89 }
90 90
91 error = sc->sc_config->acquire_bus(bus, flags); 91 error = sc->sc_config->acquire_bus(bus, flags);
92 if (error) { 92 if (error) {
93 iic_release_bus(sc->sc_i2c_parent, flags); 93 iic_release_bus(sc->sc_i2c_parent, flags);
94 } 94 }
95 95
96 return error; 96 return error;
97} 97}
98 98
99static void 99static void
100iicmux_release_bus(void * const v, int const flags) 100iicmux_release_bus(void * const v, int const flags)
101{ 101{
102 struct iicmux_bus * const bus = v; 102 struct iicmux_bus * const bus = v;
103 struct iicmux_softc * const sc = bus->mux; 103 struct iicmux_softc * const sc = bus->mux;
104 104
105 sc->sc_config->release_bus(bus, flags); 105 sc->sc_config->release_bus(bus, flags);
106 iic_release_bus(sc->sc_i2c_parent, flags); 106 iic_release_bus(sc->sc_i2c_parent, flags);
107} 107}
108 108
109static int 109static int
110iicmux_exec(void * const v, i2c_op_t const op, i2c_addr_t const addr, 110iicmux_exec(void * const v, i2c_op_t const op, i2c_addr_t const addr,
111 const void * const cmdbuf, size_t const cmdlen, void * const databuf, 111 const void * const cmdbuf, size_t const cmdlen, void * const databuf,
112 size_t const datalen, int const flags) 112 size_t const datalen, int const flags)
113{ 113{
114 struct iicmux_bus * const bus = v; 114 struct iicmux_bus * const bus = v;
115 struct iicmux_softc * const sc = bus->mux; 115 struct iicmux_softc * const sc = bus->mux;
116 116
117 return iic_exec(sc->sc_i2c_parent, op, addr, cmdbuf, cmdlen, 117 return iic_exec(sc->sc_i2c_parent, op, addr, cmdbuf, cmdlen,
118 databuf, datalen, flags); 118 databuf, datalen, flags);
119} 119}
120 120
121/*****************************************************************************/ 121/*****************************************************************************/
122 122
123static int 123static int
124iicmux_count_children(struct iicmux_softc * const sc) 124iicmux_count_children(struct iicmux_softc * const sc)
125{ 125{
126 char name[32]; 126 char name[32];
127 int child, count; 127 int child, count;
128 128
129 restart: 129 restart:
130 for (child = OF_child(sc->sc_i2c_mux_phandle), count = 0; child; 130 for (child = OF_child(sc->sc_i2c_mux_phandle), count = 0; child;
131 child = OF_peer(child)) { 131 child = OF_peer(child)) {
132 if (OF_getprop(child, "name", name, sizeof(name)) <= 0) { 132 if (OF_getprop(child, "name", name, sizeof(name)) <= 0) {
133 continue; 133 continue;
134 } 134 }
135 if (strcmp(name, "i2c-mux") == 0) { 135 if (strcmp(name, "i2c-mux") == 0) {
136 /* 136 /*
137 * The node we encountered is the acutal parent 137 * The node we encountered is the acutal parent
138 * of the i2c bus children. Stash its phandle 138 * of the i2c bus children. Stash its phandle
139 * and restart the enumeration. 139 * and restart the enumeration.
140 */ 140 */
141 sc->sc_i2c_mux_phandle = child; 141 sc->sc_i2c_mux_phandle = child;
142 goto restart; 142 goto restart;
143 } 143 }
144 count++; 144 count++;
145 } 145 }
146 146
147 return count; 147 return count;
148} 148}
149 149
150/* XXX iicbus_print() should be able to do this. */ 150/* XXX iicbus_print() should be able to do this. */
151static int 151static int
152iicmux_print(void * const aux, const char * const pnp) 152iicmux_print(void * const aux, const char * const pnp)
153{ 153{
154 i2c_tag_t const tag = aux; 154 i2c_tag_t const tag = aux;
155 struct iicmux_bus * const bus = tag->ic_cookie; 155 struct iicmux_bus * const bus = tag->ic_cookie;
156 int rv; 156 int rv;
157 157
158 rv = iicbus_print(aux, pnp); 158 rv = iicbus_print(aux, pnp);
159 aprint_normal(" bus %d", bus->busidx); 159 aprint_normal(" bus %d", bus->busidx);
160 160
161 return rv; 161 return rv;
162} 162}
163 163
164static void 164static void
165iicmux_attach_bus(struct iicmux_softc * const sc, 165iicmux_attach_bus(struct iicmux_softc * const sc,
166 uintptr_t const handle, enum i2c_cookie_type handletype, int const busidx) 166 uintptr_t const handle, enum i2c_cookie_type handletype, int const busidx)
167{ 167{
168 struct iicmux_bus * const bus = &sc->sc_busses[busidx]; 168 struct iicmux_bus * const bus = &sc->sc_busses[busidx];
169 169
170 bus->mux = sc; 170 bus->mux = sc;
171 bus->busidx = busidx; 171 bus->busidx = busidx;
172 bus->handle = handle; 172 bus->handle = handle;
173 bus->handletype = handletype; 173 bus->handletype = handletype;
174 174
175 bus->bus_data = sc->sc_config->get_bus_info(bus); 175 bus->bus_data = sc->sc_config->get_bus_info(bus);
176 if (bus->bus_data == NULL) { 176 if (bus->bus_data == NULL) {
177 aprint_error_dev(sc->sc_dev, 177 aprint_error_dev(sc->sc_dev,
178 "unable to get info for bus %d\n", busidx); 178 "unable to get info for bus %d\n", busidx);
179 return; 179 return;
180 } 180 }
181 181
182 iic_tag_init(&bus->controller); 182 iic_tag_init(&bus->controller);
183 bus->controller.ic_cookie = bus; 183 bus->controller.ic_cookie = bus;
184 bus->controller.ic_acquire_bus = iicmux_acquire_bus; 184 bus->controller.ic_acquire_bus = iicmux_acquire_bus;
185 bus->controller.ic_release_bus = iicmux_release_bus; 185 bus->controller.ic_release_bus = iicmux_release_bus;
186 bus->controller.ic_exec = iicmux_exec; 186 bus->controller.ic_exec = iicmux_exec;
187 187
188 switch (handletype) { 188 switch (handletype) {
189 case I2C_COOKIE_OF: 189 case I2C_COOKIE_OF:
190 fdtbus_register_i2c_controller(&bus->controller, 190 fdtbus_register_i2c_controller(&bus->controller,
191 (int)bus->handle); 191 (int)bus->handle);
192 192
193 fdtbus_attach_i2cbus(sc->sc_dev, (int)bus->handle, 193 fdtbus_attach_i2cbus(sc->sc_dev, (int)bus->handle,
194 &bus->controller, iicmux_print); 194 &bus->controller, iicmux_print);
195 break; 195 break;
196#if NACPICA > 0 196#if NACPICA > 0
197 case I2C_COOKIE_ACPI: { 197 case I2C_COOKIE_ACPI: {
198 struct acpi_devnode *ad = acpi_match_node((ACPI_HANDLE)handle); 198 struct acpi_devnode *ad = acpi_match_node((ACPI_HANDLE)handle);
199 KASSERT(ad != NULL); 199 KASSERT(ad != NULL);
200 struct i2cbus_attach_args iba = { 200 struct i2cbus_attach_args iba = {
201 .iba_tag = &bus->controller, 201 .iba_tag = &bus->controller,
202 .iba_child_devices = acpi_enter_i2c_devs(ad) 202 .iba_child_devices = acpi_enter_i2c_devs(NULL, ad)
203 }; 203 };
204 config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); 204 config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
205 } break; 205 } break;
206#endif 206#endif
207 default: 207 default:
208 aprint_error_dev(sc->sc_dev, "unknown handle type\n"); 208 aprint_error_dev(sc->sc_dev, "unknown handle type\n");
209 break; 209 break;
210 } 210 }
211} 211}
212 212
213static void 213static void
214iicmux_attach_fdt(struct iicmux_softc * const sc) 214iicmux_attach_fdt(struct iicmux_softc * const sc)
215{ 215{
216 /* 216 /*
217 * We start out assuming that the i2c bus nodes are children of 217 * We start out assuming that the i2c bus nodes are children of
218 * our own node. We'll adjust later if we encounter an "i2c-mux" 218 * our own node. We'll adjust later if we encounter an "i2c-mux"
219 * node when counting our children. If we encounter such a node, 219 * node when counting our children. If we encounter such a node,
220 * then it's that node that is the parent of the i2c bus children. 220 * then it's that node that is the parent of the i2c bus children.
221 */ 221 */
222 sc->sc_i2c_mux_phandle = (int)sc->sc_handle; 222 sc->sc_i2c_mux_phandle = (int)sc->sc_handle;
223 223
224 sc->sc_nbusses = iicmux_count_children(sc); 224 sc->sc_nbusses = iicmux_count_children(sc);
225 if (sc->sc_nbusses == 0) { 225 if (sc->sc_nbusses == 0) {
226 return; 226 return;
227 } 227 }
228 228
229 sc->sc_busses = kmem_zalloc(sizeof(*sc->sc_busses) * sc->sc_nbusses, 229 sc->sc_busses = kmem_zalloc(sizeof(*sc->sc_busses) * sc->sc_nbusses,
230 KM_SLEEP); 230 KM_SLEEP);
231 231
232 int child, idx; 232 int child, idx;
233 for (child = OF_child(sc->sc_i2c_mux_phandle), idx = 0; child; 233 for (child = OF_child(sc->sc_i2c_mux_phandle), idx = 0; child;
234 child = OF_peer(child), idx++) { 234 child = OF_peer(child), idx++) {
235 KASSERT(idx < sc->sc_nbusses); 235 KASSERT(idx < sc->sc_nbusses);
236 iicmux_attach_bus(sc, child, I2C_COOKIE_OF, idx); 236 iicmux_attach_bus(sc, child, I2C_COOKIE_OF, idx);
237 } 237 }
238} 238}
239 239
240#if NACPICA > 0 240#if NACPICA > 0
241static void 241static void
242iicmux_attach_acpi(struct iicmux_softc * const sc) 242iicmux_attach_acpi(struct iicmux_softc * const sc)
243{ 243{
244 ACPI_HANDLE hdl = (ACPI_HANDLE)sc->sc_handle; 244 ACPI_HANDLE hdl = (ACPI_HANDLE)sc->sc_handle;
245 struct acpi_devnode *devnode, *ad; 245 struct acpi_devnode *devnode, *ad;
246 int idx; 246 int idx;
247 247
248 devnode = acpi_match_node(hdl); 248 devnode = acpi_match_node(hdl);
249 KASSERT(devnode != NULL); 249 KASSERT(devnode != NULL);
250 250
251 /* Count child busses */ 251 /* Count child busses */
252 sc->sc_nbusses = 0; 252 sc->sc_nbusses = 0;
253 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) { 253 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
254 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE || 254 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
255 !acpi_device_present(ad->ad_handle)) { 255 !acpi_device_present(ad->ad_handle)) {
256 continue; 256 continue;
257 } 257 }
258 sc->sc_nbusses++; 258 sc->sc_nbusses++;
259 } 259 }
260 260
261 sc->sc_busses = kmem_zalloc(sizeof(*sc->sc_busses) * sc->sc_nbusses, 261 sc->sc_busses = kmem_zalloc(sizeof(*sc->sc_busses) * sc->sc_nbusses,
262 KM_SLEEP); 262 KM_SLEEP);
263 263
264 /* Attach child busses */ 264 /* Attach child busses */
265 idx = 0; 265 idx = 0;
266 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) { 266 SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
267 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE || 267 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
268 !acpi_device_present(ad->ad_handle)) { 268 !acpi_device_present(ad->ad_handle)) {
269 continue; 269 continue;
270 } 270 }
271 iicmux_attach_bus(sc, (uintptr_t)ad->ad_handle, 271 iicmux_attach_bus(sc, (uintptr_t)ad->ad_handle,
272 I2C_COOKIE_ACPI, idx); 272 I2C_COOKIE_ACPI, idx);
273 idx++; 273 idx++;
274 } 274 }
275} 275}
276#endif 276#endif
277 277
278void 278void
279iicmux_attach(struct iicmux_softc * const sc) 279iicmux_attach(struct iicmux_softc * const sc)
280{ 280{
281 /* 281 /*
282 * We expect sc->sc_handle, sc->sc_config, and sc->sc_i2c_parent 282 * We expect sc->sc_handle, sc->sc_config, and sc->sc_i2c_parent
283 * to be initialized by the front-end. 283 * to be initialized by the front-end.
284 */ 284 */
285 KASSERT(sc->sc_handle > 0); 285 KASSERT(sc->sc_handle > 0);
286 KASSERT(sc->sc_config != NULL); 286 KASSERT(sc->sc_config != NULL);
287 KASSERT(sc->sc_i2c_parent != NULL); 287 KASSERT(sc->sc_i2c_parent != NULL);
288 288
289 /* 289 /*
290 * Gather up all of the various bits of information needed 290 * Gather up all of the various bits of information needed
291 * for this particular type of i2c mux. 291 * for this particular type of i2c mux.
292 */ 292 */
293 sc->sc_mux_data = sc->sc_config->get_mux_info(sc); 293 sc->sc_mux_data = sc->sc_config->get_mux_info(sc);
294 if (sc->sc_mux_data == NULL) { 294 if (sc->sc_mux_data == NULL) {
295 aprint_error_dev(sc->sc_dev, "unable to get info for mux\n"); 295 aprint_error_dev(sc->sc_dev, "unable to get info for mux\n");
296 return; 296 return;
297 } 297 }
298 298
299 /* 299 /*
300 * Do configuration method (OF, ACPI) specific setup. 300 * Do configuration method (OF, ACPI) specific setup.
301 */ 301 */
302 switch (sc->sc_handletype) { 302 switch (sc->sc_handletype) {
303 case I2C_COOKIE_OF: 303 case I2C_COOKIE_OF:
304 iicmux_attach_fdt(sc); 304 iicmux_attach_fdt(sc);
305 break; 305 break;
306#if NACPICA > 0 306#if NACPICA > 0
307 case I2C_COOKIE_ACPI: 307 case I2C_COOKIE_ACPI:
308 iicmux_attach_acpi(sc); 308 iicmux_attach_acpi(sc);
309 break; 309 break;
310#endif 310#endif
311 default: 311 default:
312 aprint_error_dev(sc->sc_dev, "could not configure mux: " 312 aprint_error_dev(sc->sc_dev, "could not configure mux: "
313 "handle type %u not supported\n", sc->sc_handletype); 313 "handle type %u not supported\n", sc->sc_handletype);
314 break; 314 break;
315 } 315 }
316} 316}