Bug Summary

File:dev/acpi/pchgpio.c
Warning:line 640, column 2
Value stored to 'pad' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pchgpio.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/acpi/pchgpio.c
1/* $OpenBSD: pchgpio.c,v 1.15 2023/11/27 00:39:42 jsg Exp $ */
2/*
3 * Copyright (c) 2020 Mark Kettenis
4 * Copyright (c) 2020 James Hastings
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/malloc.h>
21#include <sys/systm.h>
22
23#include <dev/acpi/acpireg.h>
24#include <dev/acpi/acpivar.h>
25#include <dev/acpi/acpidev.h>
26#include <dev/acpi/amltypes.h>
27#include <dev/acpi/dsdt.h>
28
29#define PCHGPIO_MAXCOM5 5
30
31#define PCHGPIO_CONF_TXSTATE0x00000001 0x00000001
32#define PCHGPIO_CONF_RXSTATE0x00000002 0x00000002
33#define PCHGPIO_CONF_RXINV0x00800000 0x00800000
34#define PCHGPIO_CONF_RXEV_EDGE0x02000000 0x02000000
35#define PCHGPIO_CONF_RXEV_ZERO0x04000000 0x04000000
36#define PCHGPIO_CONF_RXEV_MASK0x06000000 0x06000000
37#define PCHGPIO_CONF_PADRSTCFG_MASK0xc0000000 0xc0000000
38
39#define PCHGPIO_PADBAR0x00c 0x00c
40
41struct pchgpio_group {
42 uint8_t bar;
43 uint8_t bank;
44 uint16_t base;
45 uint16_t limit;
46 int16_t gpiobase;
47};
48
49struct pchgpio_device {
50 uint16_t pad_size;
51 uint16_t gpi_is;
52 uint16_t gpi_ie;
53 const struct pchgpio_group *groups;
54 int ngroups;
55 int npins;
56};
57
58struct pchgpio_match {
59 const char *hid;
60 const struct pchgpio_device *device;
61};
62
63struct pchgpio_pincfg {
64 uint32_t pad_cfg_dw0;
65 uint32_t pad_cfg_dw1;
66 int gpi_ie;
67};
68
69struct pchgpio_intrhand {
70 int (*ih_func)(void *);
71 void *ih_arg;
72};
73
74struct pchgpio_softc {
75 struct device sc_dev;
76 struct acpi_softc *sc_acpi;
77 struct aml_node *sc_node;
78
79 bus_space_tag_t sc_memt[PCHGPIO_MAXCOM5];
80 bus_space_handle_t sc_memh[PCHGPIO_MAXCOM5];
81 void *sc_ih;
82 int sc_naddr;
83
84 const struct pchgpio_device *sc_device;
85 uint16_t sc_padbar[PCHGPIO_MAXCOM5];
86 uint16_t sc_padbase[PCHGPIO_MAXCOM5];
87 int sc_padsize;
88
89 int sc_npins;
90 struct pchgpio_pincfg *sc_pin_cfg;
91 struct pchgpio_intrhand *sc_pin_ih;
92
93 struct acpi_gpio sc_gpio;
94};
95
96int pchgpio_match(struct device *, void *, void *);
97void pchgpio_attach(struct device *, struct device *, void *);
98int pchgpio_activate(struct device *, int);
99
100const struct cfattach pchgpio_ca = {
101 sizeof(struct pchgpio_softc), pchgpio_match, pchgpio_attach,
102 NULL((void *)0), pchgpio_activate
103};
104
105struct cfdriver pchgpio_cd = {
106 NULL((void *)0), "pchgpio", DV_DULL
107};
108
109const char *pchgpio_hids[] = {
110 "INT344B",
111 "INT3450",
112 "INT3451",
113 "INT345D",
114 "INT34BB",
115 "INT34C5",
116 "INT34C6",
117 "INTC1055",
118 "INTC1056",
119 "INTC1057",
120 "INTC1085",
121 NULL((void *)0)
122};
123
124/* Sunrisepoint-LP */
125
126const struct pchgpio_group spt_lp_groups[] =
127{
128 /* Community 0 */
129 { 0, 0, 0, 23, 0 }, /* GPP_A */
130 { 0, 1, 24, 47, 24 }, /* GPP_B */
131
132 /* Community 1 */
133 { 1, 0, 48, 71, 48 }, /* GPP_C */
134 { 1, 1, 72, 95, 72 }, /* GPP_D */
135 { 1, 2, 96, 119, 96 }, /* GPP_E */
136
137 /* Community 3 */
138 { 2, 0, 120, 143, 120 }, /* GPP_F */
139 { 2, 1, 144, 151, 144 }, /* GPP_G */
140};
141
142const struct pchgpio_device spt_lp_device =
143{
144 .pad_size = 8,
145 .gpi_is = 0x100,
146 .gpi_ie = 0x120,
147 .groups = spt_lp_groups,
148 .ngroups = nitems(spt_lp_groups)(sizeof((spt_lp_groups)) / sizeof((spt_lp_groups)[0])),
149 .npins = 176,
150};
151
152/* Sunrisepoint-H */
153
154const struct pchgpio_group spt_h_groups[] =
155{
156 /* Community 0 */
157 { 0, 0, 0, 23, 0 }, /* GPP_A */
158 { 0, 1, 24, 47, 24 }, /* GPP_B */
159
160 /* Community 1 */
161 { 1, 0, 48, 71, 48 }, /* GPP_C */
162 { 1, 1, 72, 95, 72 }, /* GPP_D */
163 { 1, 2, 96, 108, 96 }, /* GPP_E */
164 { 1, 3, 109, 132, 120 }, /* GPP_F */
165 { 1, 4, 133, 156, 144 }, /* GPP_G */
166 { 1, 5, 157, 180, 168 }, /* GPP_H */
167
168 /* Community 3 */
169 { 2, 0, 181, 191, 192 }, /* GPP_I */
170};
171
172const struct pchgpio_device spt_h_device =
173{
174 .pad_size = 8,
175 .gpi_is = 0x100,
176 .gpi_ie = 0x120,
177 .groups = spt_h_groups,
178 .ngroups = nitems(spt_h_groups)(sizeof((spt_h_groups)) / sizeof((spt_h_groups)[0])),
179 .npins = 224,
180};
181
182/* Cannon Lake-H */
183
184const struct pchgpio_group cnl_h_groups[] =
185{
186 /* Community 0 */
187 { 0, 0, 0, 24, 0 }, /* GPP_A */
188 { 0, 1, 25, 50, 32 }, /* GPP_B */
189
190 /* Community 1 */
191 { 1, 0, 51, 74, 64 }, /* GPP_C */
192 { 1, 1, 75, 98, 96 }, /* GPP_D */
193 { 1, 2, 99, 106, 128 }, /* GPP_G */
194
195 /* Community 3 */
196 { 2, 0, 155, 178, 192 }, /* GPP_K */
197 { 2, 1, 179, 202, 224 }, /* GPP_H */
198 { 2, 2, 203, 215, 256 }, /* GPP_E */
199 { 2, 3, 216, 239, 288 }, /* GPP_F */
200
201 /* Community 4 */
202 { 3, 2, 269, 286, 320 }, /* GPP_I */
203 { 3, 3, 287, 298, 352 }, /* GPP_J */
204};
205
206const struct pchgpio_device cnl_h_device =
207{
208 .pad_size = 16,
209 .gpi_is = 0x100,
210 .gpi_ie = 0x120,
211 .groups = cnl_h_groups,
212 .ngroups = nitems(cnl_h_groups)(sizeof((cnl_h_groups)) / sizeof((cnl_h_groups)[0])),
213 .npins = 384,
214};
215
216/* Cannon Lake-LP */
217
218const struct pchgpio_group cnl_lp_groups[] =
219{
220 /* Community 0 */
221 { 0, 0, 0, 24, 0 }, /* GPP_A */
222 { 0, 1, 25, 50, 32 }, /* GPP_B */
223 { 0, 2, 51, 58, 64 }, /* GPP_G */
224
225 /* Community 1 */
226 { 1, 0, 68, 92, 96 }, /* GPP_D */
227 { 1, 1, 93, 116, 128 }, /* GPP_F */
228 { 1, 2, 117, 140, 160 }, /* GPP_H */
229
230 /* Community 4 */
231 { 2, 0, 181, 204, 256 }, /* GPP_C */
232 { 2, 1, 205, 228, 288 }, /* GPP_E */
233};
234
235const struct pchgpio_device cnl_lp_device =
236{
237 .pad_size = 16,
238 .gpi_is = 0x100,
239 .gpi_ie = 0x120,
240 .groups = cnl_lp_groups,
241 .ngroups = nitems(cnl_lp_groups)(sizeof((cnl_lp_groups)) / sizeof((cnl_lp_groups)[0])),
242 .npins = 320,
243};
244
245/* Tiger Lake-LP */
246
247const struct pchgpio_group tgl_lp_groups[] =
248{
249 /* Community 0 */
250 { 0, 0, 0, 25, 0 }, /* GPP_B */
251 { 0, 1, 26, 41, 32 }, /* GPP_T */
252 { 0, 2, 42, 66, 64 }, /* GPP_A */
253
254 /* Community 1 */
255 { 1, 0, 67, 74, 96 }, /* GPP_S */
256 { 1, 1, 75, 98, 128 }, /* GPP_H */
257 { 1, 2, 99, 119, 160 }, /* GPP_D */
258 { 1, 3, 120, 143, 192 }, /* GPP_U */
259
260 /* Community 4 */
261 { 2, 0, 171, 194, 256 }, /* GPP_C */
262 { 2, 1, 195, 219, 288 }, /* GPP_F */
263 { 2, 3, 226, 250, 320 }, /* GPP_E */
264
265 /* Community 5 */
266 { 3, 0, 260, 267, 352 }, /* GPP_R */
267};
268
269const struct pchgpio_device tgl_lp_device =
270{
271 .pad_size = 16,
272 .gpi_is = 0x100,
273 .gpi_ie = 0x120,
274 .groups = tgl_lp_groups,
275 .ngroups = nitems(tgl_lp_groups)(sizeof((tgl_lp_groups)) / sizeof((tgl_lp_groups)[0])),
276 .npins = 360,
277};
278
279/* Tiger Lake-H */
280
281const struct pchgpio_group tgl_h_groups[] =
282{
283 /* Community 0 */
284 { 0, 0, 0, 24, 0 }, /* GPP_A */
285 { 0, 1, 25, 44, 32 }, /* GPP_R */
286 { 0, 2, 45, 70, 64 }, /* GPP_B */
287
288 /* Community 1 */
289 { 1, 0, 79, 104, 128 }, /* GPP_D */
290 { 1, 1, 105, 128, 160 }, /* GPP_C */
291 { 1, 2, 129, 136, 192 }, /* GPP_S */
292 { 1, 3, 137, 153, 224 }, /* GPP_G */
293
294 /* Community 3 */
295 { 2, 0, 181, 193, 288 }, /* GPP_E */
296 { 2, 1, 194, 217, 320 }, /* GPP_F */
297
298 /* Community 4 */
299 { 2, 0, 218, 241, 352 }, /* GPP_H */
300 { 2, 1, 242, 251, 384 }, /* GPP_J */
301 { 2, 2, 252, 266, 416 }, /* GPP_K */
302
303 /* Community 5 */
304 { 3, 0, 267, 281, 448 }, /* GPP_I */
305};
306
307const struct pchgpio_device tgl_h_device =
308{
309 .pad_size = 16,
310 .gpi_is = 0x100,
311 .gpi_ie = 0x120,
312 .groups = tgl_h_groups,
313 .ngroups = nitems(tgl_h_groups)(sizeof((tgl_h_groups)) / sizeof((tgl_h_groups)[0])),
314 .npins = 480,
315};
316
317/* Alder Lake-S */
318
319const struct pchgpio_group adl_s_groups[] =
320{
321 /* Community 0 */
322 { 0, 0, 0, 24, 0 }, /* GPP_I */
323 { 0, 1, 25, 47, 32 }, /* GPP_R */
324 { 0, 2, 48, 59, 64 }, /* GPP_J */
325
326 /* Community 1 */
327 { 1, 0, 95, 118, 160 }, /* GPP_B */
328 { 1, 1, 119, 126, 192 }, /* GPP_G */
329 { 1, 2, 127, 150, 224 }, /* GPP_H */
330
331 /* Community 3 */
332 { 2, 1, 160, 175, 256 }, /* GPP_A */
333 { 2, 2, 176, 199, 288 }, /* GPP_C */
334
335 /* Community 4 */
336 { 3, 0, 200, 207, 320 }, /* GPP_S */
337 { 3, 1, 208, 230, 352 }, /* GPP_E */
338 { 3, 2, 231, 245, 384 }, /* GPP_K */
339 { 3, 3, 246, 269, 416 }, /* GPP_F */
340
341 /* Community 5 */
342 { 4, 0, 270, 294, 448 }, /* GPP_D */
343};
344
345const struct pchgpio_device adl_s_device =
346{
347 .pad_size = 16,
348 .gpi_is = 0x200,
349 .gpi_ie = 0x220,
350 .groups = adl_s_groups,
351 .ngroups = nitems(adl_s_groups)(sizeof((adl_s_groups)) / sizeof((adl_s_groups)[0])),
352 .npins = 480,
353};
354
355/* Alder Lake-N */
356
357const struct pchgpio_group adl_n_groups[] =
358{
359 /* Community 0 */
360 { 0, 0, 0, 25, 0 }, /* GPP_B */
361 { 0, 1, 26, 41, 32 }, /* GPP_T */
362 { 0, 2, 42, 66, 64 }, /* GPP_A */
363
364 /* Community 1 */
365 { 1, 0, 67, 74, 96 }, /* GPP_S */
366 { 1, 1, 75, 94, 128 }, /* GPP_I */
367 { 1, 2, 95, 118, 160 }, /* GPP_H */
368 { 1, 3, 119, 139, 192 }, /* GPP_D */
369
370 /* Community 4 */
371 { 2, 0, 169, 192, 256 }, /* GPP_C */
372 { 2, 1, 193, 217, 288 }, /* GPP_F */
373 { 2, 3, 224, 248, 320 }, /* GPP_E */
374
375 /* Community 5 */
376 { 3, 0, 249, 256, 352 }, /* GPP_R */
377};
378
379const struct pchgpio_device adl_n_device =
380{
381 .pad_size = 16,
382 .gpi_is = 0x100,
383 .gpi_ie = 0x120,
384 .groups = adl_n_groups,
385 .ngroups = nitems(adl_n_groups)(sizeof((adl_n_groups)) / sizeof((adl_n_groups)[0])),
386 .npins = 384,
387};
388
389struct pchgpio_match pchgpio_devices[] = {
390 { "INT344B", &spt_lp_device },
391 { "INT3450", &cnl_h_device },
392 { "INT3451", &spt_h_device },
393 { "INT345D", &spt_h_device },
394 { "INT34BB", &cnl_lp_device },
395 { "INT34C5", &tgl_lp_device },
396 { "INT34C6", &tgl_h_device },
397 { "INTC1055", &tgl_lp_device },
398 { "INTC1056", &adl_s_device },
399 { "INTC1057", &adl_n_device },
400 { "INTC1085", &adl_s_device },
401};
402
403int pchgpio_read_pin(void *, int);
404void pchgpio_write_pin(void *, int, int);
405void pchgpio_intr_establish(void *, int, int, int (*)(void *), void *);
406void pchgpio_intr_enable(void *, int);
407void pchgpio_intr_disable(void *, int);
408int pchgpio_intr(void *);
409void pchgpio_save(struct pchgpio_softc *);
410void pchgpio_restore(struct pchgpio_softc *);
411
412int
413pchgpio_match(struct device *parent, void *match, void *aux)
414{
415 struct acpi_attach_args *aaa = aux;
416 struct cfdata *cf = match;
417
418 if (aaa->aaa_naddr < 1 || aaa->aaa_nirq < 1)
419 return 0;
420 return acpi_matchhids(aaa, pchgpio_hids, cf->cf_driver->cd_name);
421}
422
423void
424pchgpio_attach(struct device *parent, struct device *self, void *aux)
425{
426 struct pchgpio_softc *sc = (struct pchgpio_softc *)self;
427 struct acpi_attach_args *aaa = aux;
428 uint16_t bar;
429 int i;
430
431 sc->sc_acpi = (struct acpi_softc *)parent;
432 sc->sc_node = aaa->aaa_node;
433 printf(" %s", sc->sc_node->name);
434
435 printf(" addr");
436
437 for (i = 0; i < aaa->aaa_naddr; i++) {
438 printf(" 0x%llx/0x%llx", aaa->aaa_addr[i], aaa->aaa_size[i]);
439
440 sc->sc_memt[i] = aaa->aaa_bst[i];
441 if (bus_space_map(sc->sc_memt[i], aaa->aaa_addr[i],
442 aaa->aaa_size[i], 0, &sc->sc_memh[i])) {
443 printf(": can't map registers\n");
444 goto unmap;
445 }
446
447 sc->sc_padbar[i] = bus_space_read_4(sc->sc_memt[i],((sc->sc_memt[i])->read_4((sc->sc_memh[i]), (0x00c))
)
448 sc->sc_memh[i], PCHGPIO_PADBAR)((sc->sc_memt[i])->read_4((sc->sc_memh[i]), (0x00c))
)
;
449 sc->sc_naddr++;
450 }
451
452 printf(" irq %d", aaa->aaa_irq[0]);
453
454 for (i = 0; i < nitems(pchgpio_devices)(sizeof((pchgpio_devices)) / sizeof((pchgpio_devices)[0])); i++) {
455 if (strcmp(pchgpio_devices[i].hid, aaa->aaa_dev) == 0) {
456 sc->sc_device = pchgpio_devices[i].device;
457 break;
458 }
459 }
460 KASSERT(sc->sc_device)((sc->sc_device) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/acpi/pchgpio.c"
, 460, "sc->sc_device"))
;
461
462 /* Figure out the first pin for each community. */
463 bar = -1;
464 for (i = 0; i < sc->sc_device->ngroups; i++) {
465 if (sc->sc_device->groups[i].bar != bar) {
466 bar = sc->sc_device->groups[i].bar;
467 sc->sc_padbase[bar] = sc->sc_device->groups[i].base;
468 }
469 }
470
471 sc->sc_padsize = sc->sc_device->pad_size;
472 sc->sc_npins = sc->sc_device->npins;
473 sc->sc_pin_cfg = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_cfg),
474 M_DEVBUF2, M_WAITOK0x0001);
475 sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
476 M_DEVBUF2, M_WAITOK0x0001 | M_ZERO0x0008);
477
478 sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0],
479 IPL_BIO0x3, pchgpio_intr, sc, sc->sc_dev.dv_xname);
480 if (sc->sc_ih == NULL((void *)0)) {
481 printf(": can't establish interrupt\n");
482 goto unmap;
483 }
484
485 sc->sc_gpio.cookie = sc;
486 sc->sc_gpio.read_pin = pchgpio_read_pin;
487 sc->sc_gpio.write_pin = pchgpio_write_pin;
488 sc->sc_gpio.intr_establish = pchgpio_intr_establish;
489 sc->sc_gpio.intr_enable = pchgpio_intr_enable;
490 sc->sc_gpio.intr_disable = pchgpio_intr_disable;
491 sc->sc_node->gpio = &sc->sc_gpio;
492
493 printf(", %d pins\n", sc->sc_npins);
494
495 acpi_register_gpio(sc->sc_acpi, sc->sc_node);
496 return;
497
498unmap:
499 free(sc->sc_pin_ih, M_DEVBUF2, sc->sc_npins * sizeof(*sc->sc_pin_ih));
500 free(sc->sc_pin_cfg, M_DEVBUF2, sc->sc_npins * sizeof(*sc->sc_pin_cfg));
501 for (i = 0; i < sc->sc_naddr; i++)
502 bus_space_unmap(sc->sc_memt[i], sc->sc_memh[i],
503 aaa->aaa_size[i]);
504}
505
506int
507pchgpio_activate(struct device *self, int act)
508{
509 struct pchgpio_softc *sc = (struct pchgpio_softc *)self;
510
511 switch (act) {
512 case DVACT_SUSPEND3:
513 pchgpio_save(sc);
514 break;
515 case DVACT_RESUME4:
516 pchgpio_restore(sc);
517 break;
518 }
519
520 return 0;
521}
522
523const struct pchgpio_group *
524pchgpio_find_group(struct pchgpio_softc *sc, int pin)
525{
526 int i, npads;
527
528 for (i = 0; i < sc->sc_device->ngroups; i++) {
529 npads = 1 + sc->sc_device->groups[i].limit -
530 sc->sc_device->groups[i].base;
531
532 if (pin >= sc->sc_device->groups[i].gpiobase &&
533 pin < sc->sc_device->groups[i].gpiobase + npads)
534 return &sc->sc_device->groups[i];
535 }
536 return NULL((void *)0);
537}
538
539int
540pchgpio_read_pin(void *cookie, int pin)
541{
542 struct pchgpio_softc *sc = cookie;
543 const struct pchgpio_group *group;
544 uint32_t reg;
545 uint16_t pad;
546 uint8_t bar;
547
548 group = pchgpio_find_group(sc, pin);
549 bar = group->bar;
550 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
551
552 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
553 sc->sc_padbar[bar] + pad * sc->sc_padsize)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
;
554
555 return !!(reg & PCHGPIO_CONF_RXSTATE0x00000002);
556}
557
558void
559pchgpio_write_pin(void *cookie, int pin, int value)
560{
561 struct pchgpio_softc *sc = cookie;
562 const struct pchgpio_group *group;
563 uint32_t reg;
564 uint16_t pad;
565 uint8_t bar;
566
567 group = pchgpio_find_group(sc, pin);
568 bar = group->bar;
569 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
570
571 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
572 sc->sc_padbar[bar] + pad * sc->sc_padsize)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
;
573 if (value)
574 reg |= PCHGPIO_CONF_TXSTATE0x00000001;
575 else
576 reg &= ~PCHGPIO_CONF_TXSTATE0x00000001;
577 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (reg)))
578 sc->sc_padbar[bar] + pad * sc->sc_padsize, reg)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (reg)))
;
579}
580
581void
582pchgpio_intr_establish(void *cookie, int pin, int flags,
583 int (*func)(void *), void *arg)
584{
585 struct pchgpio_softc *sc = cookie;
586 const struct pchgpio_group *group;
587 uint32_t reg;
588 uint16_t pad;
589 uint8_t bank, bar;
590
591 KASSERT(pin >= 0)((pin >= 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/acpi/pchgpio.c"
, 591, "pin >= 0"))
;
592
593 group = pchgpio_find_group(sc, pin);
594 if (group == NULL((void *)0))
595 return;
596
597 bar = group->bar;
598 bank = group->bank;
599 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
600
601 sc->sc_pin_ih[pin].ih_func = func;
602 sc->sc_pin_ih[pin].ih_arg = arg;
603
604 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
605 sc->sc_padbar[bar] + pad * sc->sc_padsize)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
;
606 reg &= ~(PCHGPIO_CONF_RXEV_MASK0x06000000 | PCHGPIO_CONF_RXINV0x00800000);
607 if ((flags & LR_GPIO_MODE(1L << 0)) == 1)
608 reg |= PCHGPIO_CONF_RXEV_EDGE0x02000000;
609 if ((flags & LR_GPIO_POLARITY(3L << 1)) == LR_GPIO_ACTLO(1L << 1))
610 reg |= PCHGPIO_CONF_RXINV0x00800000;
611 if ((flags & LR_GPIO_POLARITY(3L << 1)) == LR_GPIO_ACTBOTH(2L << 1))
612 reg |= PCHGPIO_CONF_RXEV_EDGE0x02000000 | PCHGPIO_CONF_RXEV_ZERO0x04000000;
613 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (reg)))
614 sc->sc_padbar[bar] + pad * sc->sc_padsize, reg)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (reg)))
;
615
616 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
617 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
618 reg |= (1 << (pin - group->gpiobase));
619 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
620 sc->sc_device->gpi_ie + bank * 4, reg)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
;
621}
622
623void
624pchgpio_intr_enable(void *cookie, int pin)
625{
626 struct pchgpio_softc *sc = cookie;
627 const struct pchgpio_group *group;
628 uint32_t reg;
629 uint16_t pad;
630 uint8_t bank, bar;
631
632 KASSERT(pin >= 0)((pin >= 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/acpi/pchgpio.c"
, 632, "pin >= 0"))
;
633
634 group = pchgpio_find_group(sc, pin);
635 if (group == NULL((void *)0))
636 return;
637
638 bar = group->bar;
639 bank = group->bank;
640 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
Value stored to 'pad' is never read
641
642 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
643 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
644 reg |= (1 << (pin - group->gpiobase));
645 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
646 sc->sc_device->gpi_ie + bank * 4, reg)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
;
647}
648
649void
650pchgpio_intr_disable(void *cookie, int pin)
651{
652 struct pchgpio_softc *sc = cookie;
653 const struct pchgpio_group *group;
654 uint32_t reg;
655 uint16_t pad;
656 uint8_t bank, bar;
657
658 KASSERT(pin >= 0)((pin >= 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/acpi/pchgpio.c"
, 658, "pin >= 0"))
;
659
660 group = pchgpio_find_group(sc, pin);
661 if (group == NULL((void *)0))
662 return;
663
664 bar = group->bar;
665 bank = group->bank;
666 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
667
668 reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
669 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
670 reg &= ~(1 << (pin - group->gpiobase));
671 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
672 sc->sc_device->gpi_ie + bank * 4, reg)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (reg)))
;
673}
674
675int
676pchgpio_intr_handle(struct pchgpio_softc *sc, int group, int bit)
677{
678 uint32_t enable;
679 int gpiobase, pin, handled = 0;
680 uint8_t bank, bar;
681
682 bar = sc->sc_device->groups[group].bar;
683 bank = sc->sc_device->groups[group].bank;
684 gpiobase = sc->sc_device->groups[group].gpiobase;
685
686 pin = gpiobase + bit;
687 if (sc->sc_pin_ih[pin].ih_func) {
688 sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
689 handled = 1;
690 } else {
691 /* Mask unhandled interrupt */
692 enable = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
693 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
694 enable &= ~(1 << bit);
695 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (enable)))
696 sc->sc_device->gpi_ie + bank * 4, enable)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (enable)))
;
697 }
698
699 return handled;
700}
701
702int
703pchgpio_intr(void *arg)
704{
705 struct pchgpio_softc *sc = arg;
706 uint32_t status, enable;
707 int group, bit, handled = 0;
708 uint16_t base, limit;
709 uint8_t bank, bar;
710
711 for (group = 0; group < sc->sc_device->ngroups; group++) {
712 bar = sc->sc_device->groups[group].bar;
713 bank = sc->sc_device->groups[group].bank;
714 base = sc->sc_device->groups[group].base;
715 limit = sc->sc_device->groups[group].limit;
716
717 status = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_is + bank * 4)))
718 sc->sc_device->gpi_is + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_is + bank * 4)))
;
719 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_is + bank * 4), (status)))
720 sc->sc_device->gpi_is + bank * 4, status)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_is + bank * 4), (status)))
;
721 enable = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
722 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
723 status &= enable;
724 if (status == 0)
725 continue;
726
727 for (bit = 0; bit <= (limit - base); bit++) {
728 if (status & (1 << bit))
729 handled |= pchgpio_intr_handle(sc, group, bit);
730 }
731 }
732
733 return handled;
734}
735
736void
737pchgpio_save_pin(struct pchgpio_softc *sc, int pin)
738{
739 const struct pchgpio_group *group;
740 uint32_t gpi_ie;
741 uint16_t pad;
742 uint8_t bank, bar;
743
744 group = pchgpio_find_group(sc, pin);
745 if (group == NULL((void *)0))
746 return;
747
748 bar = group->bar;
749 bank = group->bank;
750 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
751
752 sc->sc_pin_cfg[pin].pad_cfg_dw0 =
753 bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
754 sc->sc_padbar[bar] + pad * sc->sc_padsize)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
;
755 sc->sc_pin_cfg[pin].pad_cfg_dw1 =
756 bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize + 4)))
757 sc->sc_padbar[bar] + pad * sc->sc_padsize + 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize + 4)))
;
758
759 gpi_ie = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
760 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
761 sc->sc_pin_cfg[pin].gpi_ie = (gpi_ie & (1 << (pin - group->gpiobase)));
762}
763
764void
765pchgpio_save(struct pchgpio_softc *sc)
766{
767 int pin;
768
769 for (pin = 0; pin < sc->sc_npins; pin++)
770 pchgpio_save_pin(sc, pin);
771}
772
773void
774pchgpio_restore_pin(struct pchgpio_softc *sc, int pin)
775{
776 const struct pchgpio_group *group;
777 int restore = 0;
778 uint32_t pad_cfg_dw0, gpi_ie;
779 uint16_t pad;
780 uint8_t bank, bar;
781
782 group = pchgpio_find_group(sc, pin);
783 if (group == NULL((void *)0))
784 return;
785
786 bar = group->bar;
787 bank = group->bank;
788 pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar];
789
790 pad_cfg_dw0 = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
791 sc->sc_padbar[bar] + pad * sc->sc_padsize)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_padbar[bar] + pad * sc->sc_padsize)))
;
792
793 if (sc->sc_pin_ih[pin].ih_func)
794 restore = 1;
795
796 /*
797 * The BIOS on Lenovo Thinkpads based on Intel's Tiger Lake
798 * platform have a bug where the GPIO pin that is used for the
799 * touchpad interrupt gets reset when entering S3 and isn't
800 * properly restored upon resume. We detect this issue by
801 * comparing the bits in the PAD_CFG_DW0 register PADRSTCFG
802 * field before suspend and after resume and restore the pin
803 * configuration if the bits don't match.
804 */
805 if ((sc->sc_pin_cfg[pin].pad_cfg_dw0 & PCHGPIO_CONF_PADRSTCFG_MASK0xc0000000) !=
806 (pad_cfg_dw0 & PCHGPIO_CONF_PADRSTCFG_MASK0xc0000000))
807 restore = 1;
808
809 if (restore) {
810 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (sc->sc_pin_cfg
[pin].pad_cfg_dw0)))
811 sc->sc_padbar[bar] + pad * sc->sc_padsize,((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (sc->sc_pin_cfg
[pin].pad_cfg_dw0)))
812 sc->sc_pin_cfg[pin].pad_cfg_dw0)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize), (sc->sc_pin_cfg
[pin].pad_cfg_dw0)))
;
813 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize + 4), (sc->sc_pin_cfg
[pin].pad_cfg_dw1)))
814 sc->sc_padbar[bar] + pad * sc->sc_padsize + 4,((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize + 4), (sc->sc_pin_cfg
[pin].pad_cfg_dw1)))
815 sc->sc_pin_cfg[pin].pad_cfg_dw1)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_padbar[bar] + pad * sc->sc_padsize + 4), (sc->sc_pin_cfg
[pin].pad_cfg_dw1)))
;
816
817 gpi_ie = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
818 sc->sc_device->gpi_ie + bank * 4)((sc->sc_memt[bar])->read_4((sc->sc_memh[bar]), (sc->
sc_device->gpi_ie + bank * 4)))
;
819 if (sc->sc_pin_cfg[pin].gpi_ie)
820 gpi_ie |= (1 << (pin - group->gpiobase));
821 else
822 gpi_ie &= ~(1 << (pin - group->gpiobase));
823 bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar],((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (gpi_ie)))
824 sc->sc_device->gpi_ie + bank * 4, gpi_ie)((sc->sc_memt[bar])->write_4((sc->sc_memh[bar]), (sc
->sc_device->gpi_ie + bank * 4), (gpi_ie)))
;
825 }
826}
827
828void
829pchgpio_restore(struct pchgpio_softc *sc)
830{
831 int pin;
832
833 for (pin = 0; pin < sc->sc_npins; pin++)
834 pchgpio_restore_pin(sc, pin);
835}