Mon Jun 6 14:33:32 2011 UTC ()
Rename to use PCI_PRODUCT_INTEL_82801DBM_LPC


(msaitoh)
diff -r1.47 -r1.48 src/sys/arch/i386/pci/pci_intr_fixup.c
diff -r1.29 -r1.30 src/sys/arch/x86/pci/ichlpcib.c

cvs diff -r1.47 -r1.48 src/sys/arch/i386/pci/pci_intr_fixup.c (switch to unified diff)

--- src/sys/arch/i386/pci/pci_intr_fixup.c 2008/04/28 20:23:25 1.47
+++ src/sys/arch/i386/pci/pci_intr_fixup.c 2011/06/06 14:33:31 1.48
@@ -1,951 +1,951 @@ @@ -1,951 +1,951 @@
1/* $NetBSD: pci_intr_fixup.c,v 1.47 2008/04/28 20:23:25 martin Exp $ */ 1/* $NetBSD: pci_intr_fixup.c,v 1.48 2011/06/06 14:33:31 msaitoh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999 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 of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center. 9 * NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1999, by UCHIYAMA Yasushi 34 * Copyright (c) 1999, by UCHIYAMA Yasushi
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. The name of the developer may NOT be used to endorse or promote products 42 * 2. The name of the developer may NOT be used to endorse or promote products
43 * derived from this software without specific prior written permission. 43 * derived from this software without specific prior written permission.
44 *  44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND  45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE  48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.  55 * SUCH DAMAGE.
56 */ 56 */
57 57
58/* 58/*
59 * PCI Interrupt Router support. 59 * PCI Interrupt Router support.
60 */ 60 */
61 61
62#include <sys/cdefs.h> 62#include <sys/cdefs.h>
63__KERNEL_RCSID(0, "$NetBSD: pci_intr_fixup.c,v 1.47 2008/04/28 20:23:25 martin Exp $"); 63__KERNEL_RCSID(0, "$NetBSD: pci_intr_fixup.c,v 1.48 2011/06/06 14:33:31 msaitoh Exp $");
64 64
65#include "opt_pcibios.h" 65#include "opt_pcibios.h"
66#include "opt_pcifixup.h" 66#include "opt_pcifixup.h"
67 67
68#include <sys/param.h> 68#include <sys/param.h>
69#include <sys/systm.h> 69#include <sys/systm.h>
70#include <sys/kernel.h> 70#include <sys/kernel.h>
71#include <sys/malloc.h> 71#include <sys/malloc.h>
72#include <sys/queue.h> 72#include <sys/queue.h>
73#include <sys/device.h> 73#include <sys/device.h>
74 74
75#include <machine/bus.h> 75#include <machine/bus.h>
76#include <machine/intr.h> 76#include <machine/intr.h>
77 77
78#include <dev/pci/pcireg.h> 78#include <dev/pci/pcireg.h>
79#include <dev/pci/pcivar.h> 79#include <dev/pci/pcivar.h>
80#include <dev/pci/pcidevs.h> 80#include <dev/pci/pcidevs.h>
81 81
82#include <i386/pci/pci_intr_fixup.h> 82#include <i386/pci/pci_intr_fixup.h>
83#include <i386/pci/pcibios.h> 83#include <i386/pci/pcibios.h>
84 84
85struct pciintr_link_map { 85struct pciintr_link_map {
86 int link; 86 int link;
87 int clink; 87 int clink;
88 int irq; 88 int irq;
89 uint16_t bitmap; 89 uint16_t bitmap;
90 int fixup_stage; 90 int fixup_stage;
91 SIMPLEQ_ENTRY(pciintr_link_map) list; 91 SIMPLEQ_ENTRY(pciintr_link_map) list;
92}; 92};
93 93
94pciintr_icu_tag_t pciintr_icu_tag; 94pciintr_icu_tag_t pciintr_icu_tag;
95pciintr_icu_handle_t pciintr_icu_handle; 95pciintr_icu_handle_t pciintr_icu_handle;
96 96
97#ifdef PCIBIOS_IRQS_HINT 97#ifdef PCIBIOS_IRQS_HINT
98int pcibios_irqs_hint = PCIBIOS_IRQS_HINT; 98int pcibios_irqs_hint = PCIBIOS_IRQS_HINT;
99#endif 99#endif
100 100
101struct pciintr_link_map *pciintr_link_lookup(int); 101struct pciintr_link_map *pciintr_link_lookup(int);
102struct pciintr_link_map *pciintr_link_alloc(struct pcibios_intr_routing *, 102struct pciintr_link_map *pciintr_link_alloc(struct pcibios_intr_routing *,
103 int); 103 int);
104struct pcibios_intr_routing *pciintr_pir_lookup(int, int); 104struct pcibios_intr_routing *pciintr_pir_lookup(int, int);
105static int pciintr_bitmap_count_irq(int, int *); 105static int pciintr_bitmap_count_irq(int, int *);
106static int pciintr_bitmap_find_lowest_irq(int, int *); 106static int pciintr_bitmap_find_lowest_irq(int, int *);
107int pciintr_link_init (void); 107int pciintr_link_init (void);
108#ifdef PCIBIOS_INTR_GUESS 108#ifdef PCIBIOS_INTR_GUESS
109int pciintr_guess_irq(void); 109int pciintr_guess_irq(void);
110#endif 110#endif
111int pciintr_link_fixup(void); 111int pciintr_link_fixup(void);
112int pciintr_link_route(uint16_t *); 112int pciintr_link_route(uint16_t *);
113int pciintr_irq_release(uint16_t *); 113int pciintr_irq_release(uint16_t *);
114int pciintr_header_fixup(pci_chipset_tag_t); 114int pciintr_header_fixup(pci_chipset_tag_t);
115void pciintr_do_header_fixup(pci_chipset_tag_t, pcitag_t, void*); 115void pciintr_do_header_fixup(pci_chipset_tag_t, pcitag_t, void*);
116 116
117SIMPLEQ_HEAD(, pciintr_link_map) pciintr_link_map_list; 117SIMPLEQ_HEAD(, pciintr_link_map) pciintr_link_map_list;
118 118
119const struct pciintr_icu_table { 119const struct pciintr_icu_table {
120 pci_vendor_id_t piit_vendor; 120 pci_vendor_id_t piit_vendor;
121 pci_product_id_t piit_product; 121 pci_product_id_t piit_product;
122 int (*piit_init)(pci_chipset_tag_t, 122 int (*piit_init)(pci_chipset_tag_t,
123 bus_space_tag_t, pcitag_t, pciintr_icu_tag_t *, 123 bus_space_tag_t, pcitag_t, pciintr_icu_tag_t *,
124 pciintr_icu_handle_t *); 124 pciintr_icu_handle_t *);
125 void (*piit_uninit)(pciintr_icu_handle_t); 125 void (*piit_uninit)(pciintr_icu_handle_t);
126} pciintr_icu_table[] = { 126} pciintr_icu_table[] = {
127 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371MX, 127 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371MX,
128 piix_init, piix_uninit }, 128 piix_init, piix_uninit },
129 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371AB_ISA, 129 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371AB_ISA,
130 piix_init, piix_uninit }, 130 piix_init, piix_uninit },
131 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371FB_ISA, 131 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371FB_ISA,
132 piix_init, piix_uninit }, 132 piix_init, piix_uninit },
133 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371SB_ISA, 133 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371SB_ISA,
134 piix_init, piix_uninit }, 134 piix_init, piix_uninit },
135 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_ISA, 135 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_ISA,
136 piix_init, piix_uninit }, 136 piix_init, piix_uninit },
137 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 137 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC,
138 piix_init, piix_uninit }, /* ICH */ 138 piix_init, piix_uninit }, /* ICH */
139 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC, 139 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC,
140 piix_init, piix_uninit }, /* ICH0 */ 140 piix_init, piix_uninit }, /* ICH0 */
141 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 141 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC,
142 ich_init, NULL }, /* ICH2 */ 142 ich_init, NULL }, /* ICH2 */
143 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 143 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC,
144 ich_init, NULL }, /* ICH2M */ 144 ich_init, NULL }, /* ICH2M */
145 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 145 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC,
146 ich_init, NULL }, /* ICH3S */ 146 ich_init, NULL }, /* ICH3S */
147 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 147 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC,
148 ich_init, NULL }, /* ICH3M */ 148 ich_init, NULL }, /* ICH3M */
149 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 149 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC,
150 ich_init, NULL }, /* ICH4 */ 150 ich_init, NULL }, /* ICH4 */
151 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_ISA, 151 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DBM_LPC,
152 ich_init, NULL }, /* ICH4M */ 152 ich_init, NULL }, /* ICH4M */
153 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC, 153 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC,
154 ich_init, NULL }, /* ICH5 */ 154 ich_init, NULL }, /* ICH5 */
155 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC, 155 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC,
156 ich_init, NULL }, /* ICH6/ICH6R */ 156 ich_init, NULL }, /* ICH6/ICH6R */
157 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC, 157 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC,
158 ich_init, NULL }, /* ICH6M */ 158 ich_init, NULL }, /* ICH6M */
159 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC, 159 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC,
160 ich_init, NULL }, /* ICH7/ICH7R */ 160 ich_init, NULL }, /* ICH7/ICH7R */
161 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC, 161 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC,
162 ich_init, NULL }, /* ICH7-M */ 162 ich_init, NULL }, /* ICH7-M */
163 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 163 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC,
164 ich_init, NULL }, /* ICH7DH/ICH7-M DH */ 164 ich_init, NULL }, /* ICH7DH/ICH7-M DH */
165 165
166 { PCI_VENDOR_OPTI, PCI_PRODUCT_OPTI_82C558, 166 { PCI_VENDOR_OPTI, PCI_PRODUCT_OPTI_82C558,
167 opti82c558_init, NULL }, 167 opti82c558_init, NULL },
168 { PCI_VENDOR_OPTI, PCI_PRODUCT_OPTI_82C700, 168 { PCI_VENDOR_OPTI, PCI_PRODUCT_OPTI_82C700,
169 opti82c700_init, NULL }, 169 opti82c700_init, NULL },
170 170
171 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C586_ISA, 171 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C586_ISA,
172 via82c586_init, NULL }, 172 via82c586_init, NULL },
173 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C596A, 173 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C596A,
174 via82c586_init, NULL }, 174 via82c586_init, NULL },
175 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C686A_ISA, 175 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT82C686A_ISA,
176 via82c586_init, NULL }, 176 via82c586_init, NULL },
177 177
178 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8231, 178 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8231,
179 via8231_init, NULL }, 179 via8231_init, NULL },
180 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233, 180 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233,
181 via82c586_init, NULL }, 181 via82c586_init, NULL },
182 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233A, 182 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8233A,
183 via8231_init, NULL }, 183 via8231_init, NULL },
184 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8235, 184 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8235,
185 via8231_init, NULL }, 185 via8231_init, NULL },
186 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8237, 186 { PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VT8237,
187 via8231_init, NULL }, 187 via8231_init, NULL },
188 188
189 189
190 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_85C503, 190 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_85C503,
191 sis85c503_init, NULL }, 191 sis85c503_init, NULL },
192 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_962, 192 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_962,
193 sis85c503_init, NULL }, 193 sis85c503_init, NULL },
194 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_963, 194 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_963,
195 sis85c503_init, NULL }, 195 sis85c503_init, NULL },
196 196
197 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC756_PMC, 197 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC756_PMC,
198 amd756_init, NULL }, 198 amd756_init, NULL },
199 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC766_PMC, 199 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC766_PMC,
200 amd756_init, NULL }, 200 amd756_init, NULL },
201 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_PMC, 201 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_PMC,
202 amd756_init, NULL }, 202 amd756_init, NULL },
203 203
204 { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1533, 204 { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1533,
205 ali1543_init, NULL }, 205 ali1543_init, NULL },
206 { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1543, 206 { PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M1543,
207 ali1543_init, NULL }, 207 ali1543_init, NULL },
208 208
209 { 0, 0, 209 { 0, 0,
210 NULL, NULL }, 210 NULL, NULL },
211}; 211};
212 212
213const struct pciintr_icu_table *pciintr_icu_lookup(pcireg_t); 213const struct pciintr_icu_table *pciintr_icu_lookup(pcireg_t);
214 214
215const struct pciintr_icu_table * 215const struct pciintr_icu_table *
216pciintr_icu_lookup(pcireg_t id) 216pciintr_icu_lookup(pcireg_t id)
217{ 217{
218 const struct pciintr_icu_table *piit; 218 const struct pciintr_icu_table *piit;
219 219
220 for (piit = pciintr_icu_table; 220 for (piit = pciintr_icu_table;
221 piit->piit_init != NULL; 221 piit->piit_init != NULL;
222 piit++) { 222 piit++) {
223 if (PCI_VENDOR(id) == piit->piit_vendor && 223 if (PCI_VENDOR(id) == piit->piit_vendor &&
224 PCI_PRODUCT(id) == piit->piit_product) 224 PCI_PRODUCT(id) == piit->piit_product)
225 return (piit); 225 return (piit);
226 } 226 }
227 227
228 return (NULL); 228 return (NULL);
229} 229}
230 230
231struct pciintr_link_map * 231struct pciintr_link_map *
232pciintr_link_lookup(int link) 232pciintr_link_lookup(int link)
233{ 233{
234 struct pciintr_link_map *l; 234 struct pciintr_link_map *l;
235 235
236 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 236 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
237 if (l->link == link) 237 if (l->link == link)
238 return (l); 238 return (l);
239 } 239 }
240 240
241 return (NULL); 241 return (NULL);
242} 242}
243 243
244struct pciintr_link_map * 244struct pciintr_link_map *
245pciintr_link_alloc(struct pcibios_intr_routing *pir, int pin) 245pciintr_link_alloc(struct pcibios_intr_routing *pir, int pin)
246{ 246{
247 int link = pir->linkmap[pin].link, clink, irq; 247 int link = pir->linkmap[pin].link, clink, irq;
248 struct pciintr_link_map *l, *lstart; 248 struct pciintr_link_map *l, *lstart;
249 249
250 if (pciintr_icu_tag != NULL) { /* compatible PCI ICU found */ 250 if (pciintr_icu_tag != NULL) { /* compatible PCI ICU found */
251 /* 251 /*
252 * Get the canonical link value for this entry. 252 * Get the canonical link value for this entry.
253 */ 253 */
254 if (pciintr_icu_getclink(pciintr_icu_tag, pciintr_icu_handle, 254 if (pciintr_icu_getclink(pciintr_icu_tag, pciintr_icu_handle,
255 link, &clink) != 0) { 255 link, &clink) != 0) {
256 /* 256 /*
257 * ICU doesn't understand the link value. 257 * ICU doesn't understand the link value.
258 * Just ignore this PIR entry. 258 * Just ignore this PIR entry.
259 */ 259 */
260#ifdef DIAGNOSTIC 260#ifdef DIAGNOSTIC
261 printf("pciintr_link_alloc: bus %d device %d: " 261 printf("pciintr_link_alloc: bus %d device %d: "
262 "link 0x%02x invalid\n", 262 "link 0x%02x invalid\n",
263 pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link); 263 pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link);
264#endif 264#endif
265 return (NULL); 265 return (NULL);
266 } 266 }
267 267
268 /* 268 /*
269 * Check the link value by asking the ICU for the 269 * Check the link value by asking the ICU for the
270 * canonical link value. 270 * canonical link value.
271 * Also, determine if this PIRQ is mapped to an IRQ. 271 * Also, determine if this PIRQ is mapped to an IRQ.
272 */ 272 */
273 if (pciintr_icu_get_intr(pciintr_icu_tag, pciintr_icu_handle, 273 if (pciintr_icu_get_intr(pciintr_icu_tag, pciintr_icu_handle,
274 clink, &irq) != 0) { 274 clink, &irq) != 0) {
275 /* 275 /*
276 * ICU doesn't understand the canonical link value. 276 * ICU doesn't understand the canonical link value.
277 * Just ignore this PIR entry. 277 * Just ignore this PIR entry.
278 */ 278 */
279#ifdef DIAGNOSTIC 279#ifdef DIAGNOSTIC
280 printf("pciintr_link_alloc: " 280 printf("pciintr_link_alloc: "
281 "bus %d device %d link 0x%02x: " 281 "bus %d device %d link 0x%02x: "
282 "PIRQ 0x%02x invalid\n", 282 "PIRQ 0x%02x invalid\n",
283 pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link, 283 pir->bus, PIR_DEVFUNC_DEVICE(pir->device), link,
284 clink); 284 clink);
285#endif 285#endif
286 return (NULL); 286 return (NULL);
287 } 287 }
288 } 288 }
289 289
290 l = malloc(sizeof(*l), M_DEVBUF, M_NOWAIT); 290 l = malloc(sizeof(*l), M_DEVBUF, M_NOWAIT);
291 if (l == NULL) 291 if (l == NULL)
292 panic("pciintr_link_alloc"); 292 panic("pciintr_link_alloc");
293 293
294 memset(l, 0, sizeof(*l)); 294 memset(l, 0, sizeof(*l));
295 295
296 l->link = link; 296 l->link = link;
297 l->bitmap = pir->linkmap[pin].bitmap; 297 l->bitmap = pir->linkmap[pin].bitmap;
298 if (pciintr_icu_tag != NULL) { /* compatible PCI ICU found */ 298 if (pciintr_icu_tag != NULL) { /* compatible PCI ICU found */
299 l->clink = clink; 299 l->clink = clink;
300 l->irq = irq; /* maybe X86_PCI_INTERRUPT_LINE_NO_CONNECTION */ 300 l->irq = irq; /* maybe X86_PCI_INTERRUPT_LINE_NO_CONNECTION */
301 } else { 301 } else {
302 l->clink = link; /* only for PCIBIOSVERBOSE diagnostic */ 302 l->clink = link; /* only for PCIBIOSVERBOSE diagnostic */
303 l->irq = X86_PCI_INTERRUPT_LINE_NO_CONNECTION; 303 l->irq = X86_PCI_INTERRUPT_LINE_NO_CONNECTION;
304 } 304 }
305 305
306 lstart = SIMPLEQ_FIRST(&pciintr_link_map_list); 306 lstart = SIMPLEQ_FIRST(&pciintr_link_map_list);
307 if (lstart == NULL || lstart->link < l->link) 307 if (lstart == NULL || lstart->link < l->link)
308 SIMPLEQ_INSERT_TAIL(&pciintr_link_map_list, l, list); 308 SIMPLEQ_INSERT_TAIL(&pciintr_link_map_list, l, list);
309 else 309 else
310 SIMPLEQ_INSERT_HEAD(&pciintr_link_map_list, l, list); 310 SIMPLEQ_INSERT_HEAD(&pciintr_link_map_list, l, list);
311 311
312 return (l); 312 return (l);
313} 313}
314 314
315struct pcibios_intr_routing * 315struct pcibios_intr_routing *
316pciintr_pir_lookup(int bus, int device) 316pciintr_pir_lookup(int bus, int device)
317{ 317{
318 struct pcibios_intr_routing *pir; 318 struct pcibios_intr_routing *pir;
319 int entry; 319 int entry;
320 320
321 if (pcibios_pir_table == NULL) 321 if (pcibios_pir_table == NULL)
322 return (NULL); 322 return (NULL);
323 323
324 for (entry = 0; entry < pcibios_pir_table_nentries; entry++) { 324 for (entry = 0; entry < pcibios_pir_table_nentries; entry++) {
325 pir = &pcibios_pir_table[entry]; 325 pir = &pcibios_pir_table[entry];
326 if (pir->bus == bus && 326 if (pir->bus == bus &&
327 PIR_DEVFUNC_DEVICE(pir->device) == device) 327 PIR_DEVFUNC_DEVICE(pir->device) == device)
328 return (pir); 328 return (pir);
329 } 329 }
330 330
331 return (NULL); 331 return (NULL);
332} 332}
333 333
334static int 334static int
335pciintr_bitmap_count_irq(int irq_bitmap, int *irqp) 335pciintr_bitmap_count_irq(int irq_bitmap, int *irqp)
336{ 336{
337 int i, bit, count = 0, irq = X86_PCI_INTERRUPT_LINE_NO_CONNECTION; 337 int i, bit, count = 0, irq = X86_PCI_INTERRUPT_LINE_NO_CONNECTION;
338 338
339 if (irq_bitmap != 0) { 339 if (irq_bitmap != 0) {
340 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) { 340 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
341 if (irq_bitmap & bit) { 341 if (irq_bitmap & bit) {
342 irq = i; 342 irq = i;
343 count++; 343 count++;
344 } 344 }
345 } 345 }
346 } 346 }
347 *irqp = irq; 347 *irqp = irq;
348 return (count); 348 return (count);
349} 349}
350 350
351static int 351static int
352pciintr_bitmap_find_lowest_irq(int irq_bitmap, int *irqp) 352pciintr_bitmap_find_lowest_irq(int irq_bitmap, int *irqp)
353{ 353{
354 int i, bit; 354 int i, bit;
355 355
356 if (irq_bitmap != 0) { 356 if (irq_bitmap != 0) {
357 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) { 357 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
358 if (irq_bitmap & bit) { 358 if (irq_bitmap & bit) {
359 *irqp = i; 359 *irqp = i;
360 return (1); /* found */ 360 return (1); /* found */
361 } 361 }
362 } 362 }
363 } 363 }
364 return (0); /* not found */ 364 return (0); /* not found */
365} 365}
366 366
367int 367int
368pciintr_link_init(void) 368pciintr_link_init(void)
369{ 369{
370 int entry, pin, link; 370 int entry, pin, link;
371 struct pcibios_intr_routing *pir; 371 struct pcibios_intr_routing *pir;
372 struct pciintr_link_map *l; 372 struct pciintr_link_map *l;
373 373
374 if (pcibios_pir_table == NULL) { 374 if (pcibios_pir_table == NULL) {
375 /* No PIR table; can't do anything. */ 375 /* No PIR table; can't do anything. */
376 printf("pciintr_link_init: no PIR table\n"); 376 printf("pciintr_link_init: no PIR table\n");
377 return (1); 377 return (1);
378 } 378 }
379 379
380 SIMPLEQ_INIT(&pciintr_link_map_list); 380 SIMPLEQ_INIT(&pciintr_link_map_list);
381 381
382 for (entry = 0; entry < pcibios_pir_table_nentries; entry++) { 382 for (entry = 0; entry < pcibios_pir_table_nentries; entry++) {
383 pir = &pcibios_pir_table[entry]; 383 pir = &pcibios_pir_table[entry];
384 for (pin = 0; pin < PCI_INTERRUPT_PIN_MAX; pin++) { 384 for (pin = 0; pin < PCI_INTERRUPT_PIN_MAX; pin++) {
385 link = pir->linkmap[pin].link; 385 link = pir->linkmap[pin].link;
386 if (link == 0) { 386 if (link == 0) {
387 /* No connection for this pin. */ 387 /* No connection for this pin. */
388 continue; 388 continue;
389 } 389 }
390 /* 390 /*
391 * Multiple devices may be wired to the same 391 * Multiple devices may be wired to the same
392 * interrupt; check to see if we've seen this 392 * interrupt; check to see if we've seen this
393 * one already. If not, allocate a new link 393 * one already. If not, allocate a new link
394 * map entry and stuff it in the map. 394 * map entry and stuff it in the map.
395 */ 395 */
396 l = pciintr_link_lookup(link); 396 l = pciintr_link_lookup(link);
397 if (l == NULL) { 397 if (l == NULL) {
398 (void) pciintr_link_alloc(pir, pin); 398 (void) pciintr_link_alloc(pir, pin);
399 } else if (pir->linkmap[pin].bitmap != l->bitmap) { 399 } else if (pir->linkmap[pin].bitmap != l->bitmap) {
400 /* 400 /*
401 * violates PCI IRQ Routing Table Specification 401 * violates PCI IRQ Routing Table Specification
402 */ 402 */
403#ifdef DIAGNOSTIC 403#ifdef DIAGNOSTIC
404 printf("pciintr_link_init: " 404 printf("pciintr_link_init: "
405 "bus %d device %d link 0x%02x: " 405 "bus %d device %d link 0x%02x: "
406 "bad irq bitmap 0x%04x, " 406 "bad irq bitmap 0x%04x, "
407 "should be 0x%04x\n", 407 "should be 0x%04x\n",
408 pir->bus, PIR_DEVFUNC_DEVICE(pir->device), 408 pir->bus, PIR_DEVFUNC_DEVICE(pir->device),
409 link, pir->linkmap[pin].bitmap, l->bitmap); 409 link, pir->linkmap[pin].bitmap, l->bitmap);
410#endif 410#endif
411 /* safer value. */  411 /* safer value. */
412 l->bitmap &= pir->linkmap[pin].bitmap; 412 l->bitmap &= pir->linkmap[pin].bitmap;
413 /* XXX - or, should ignore this entry? */ 413 /* XXX - or, should ignore this entry? */
414 } 414 }
415 } 415 }
416 } 416 }
417 417
418 return (0); 418 return (0);
419} 419}
420 420
421#ifdef PCIBIOS_INTR_GUESS 421#ifdef PCIBIOS_INTR_GUESS
422/* 422/*
423 * No compatible PCI ICU found. 423 * No compatible PCI ICU found.
424 * Hopes the BIOS already setup the ICU. 424 * Hopes the BIOS already setup the ICU.
425 */ 425 */
426int 426int
427pciintr_guess_irq(void) 427pciintr_guess_irq(void)
428{ 428{
429 struct pciintr_link_map *l; 429 struct pciintr_link_map *l;
430 int irq, guessed = 0; 430 int irq, guessed = 0;
431 431
432 /* 432 /*
433 * Stage 1: If only one IRQ is available for the link, use it. 433 * Stage 1: If only one IRQ is available for the link, use it.
434 */ 434 */
435 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 435 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
436 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) 436 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
437 continue; 437 continue;
438 if (pciintr_bitmap_count_irq(l->bitmap, &irq) == 1) { 438 if (pciintr_bitmap_count_irq(l->bitmap, &irq) == 1) {
439 l->irq = irq; 439 l->irq = irq;
440 l->fixup_stage = 1; 440 l->fixup_stage = 1;
441#ifdef PCIINTR_DEBUG 441#ifdef PCIINTR_DEBUG
442 printf("pciintr_guess_irq (stage 1): " 442 printf("pciintr_guess_irq (stage 1): "
443 "guessing PIRQ 0x%02x to be IRQ %d\n", 443 "guessing PIRQ 0x%02x to be IRQ %d\n",
444 l->clink, l->irq); 444 l->clink, l->irq);
445#endif 445#endif
446 guessed = 1; 446 guessed = 1;
447 } 447 }
448 } 448 }
449 449
450 return (guessed ? 0 : -1); 450 return (guessed ? 0 : -1);
451} 451}
452#endif /* PCIBIOS_INTR_GUESS */ 452#endif /* PCIBIOS_INTR_GUESS */
453 453
454int 454int
455pciintr_link_fixup(void) 455pciintr_link_fixup(void)
456{ 456{
457 struct pciintr_link_map *l; 457 struct pciintr_link_map *l;
458 int irq; 458 int irq;
459 uint16_t pciirq = 0; 459 uint16_t pciirq = 0;
460 460
461 /* 461 /*
462 * First stage: Attempt to connect PIRQs which aren't 462 * First stage: Attempt to connect PIRQs which aren't
463 * yet connected. 463 * yet connected.
464 */ 464 */
465 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 465 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
466 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 466 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
467 /* 467 /*
468 * Interrupt is already connected. Don't do 468 * Interrupt is already connected. Don't do
469 * anything to it. 469 * anything to it.
470 * In this case, l->fixup_stage == 0. 470 * In this case, l->fixup_stage == 0.
471 */ 471 */
472 pciirq |= 1 << l->irq; 472 pciirq |= 1 << l->irq;
473#ifdef PCIINTR_DEBUG 473#ifdef PCIINTR_DEBUG
474 printf("pciintr_link_fixup: PIRQ 0x%02x already " 474 printf("pciintr_link_fixup: PIRQ 0x%02x already "
475 "connected to IRQ %d\n", l->clink, l->irq); 475 "connected to IRQ %d\n", l->clink, l->irq);
476#endif 476#endif
477 continue; 477 continue;
478 } 478 }
479 /* 479 /*
480 * Interrupt isn't connected. Attempt to assign it to an IRQ. 480 * Interrupt isn't connected. Attempt to assign it to an IRQ.
481 */ 481 */
482#ifdef PCIINTR_DEBUG 482#ifdef PCIINTR_DEBUG
483 printf("pciintr_link_fixup: PIRQ 0x%02x not connected", 483 printf("pciintr_link_fixup: PIRQ 0x%02x not connected",
484 l->clink); 484 l->clink);
485#endif 485#endif
486 /* 486 /*
487 * Just do the easy case now; we'll defer the harder ones 487 * Just do the easy case now; we'll defer the harder ones
488 * to Stage 2. 488 * to Stage 2.
489 */ 489 */
490 if (pciintr_bitmap_count_irq(l->bitmap, &irq) == 1) { 490 if (pciintr_bitmap_count_irq(l->bitmap, &irq) == 1) {
491 l->irq = irq; 491 l->irq = irq;
492 l->fixup_stage = 1; 492 l->fixup_stage = 1;
493 pciirq |= 1 << irq; 493 pciirq |= 1 << irq;
494#ifdef PCIINTR_DEBUG 494#ifdef PCIINTR_DEBUG
495 printf(", assigning IRQ %d", l->irq); 495 printf(", assigning IRQ %d", l->irq);
496#endif 496#endif
497 } 497 }
498#ifdef PCIINTR_DEBUG 498#ifdef PCIINTR_DEBUG
499 printf("\n"); 499 printf("\n");
500#endif 500#endif
501 } 501 }
502 502
503 /* 503 /*
504 * Stage 2: Attempt to connect PIRQs which we didn't 504 * Stage 2: Attempt to connect PIRQs which we didn't
505 * connect in Stage 1. 505 * connect in Stage 1.
506 */ 506 */
507 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 507 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
508 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) 508 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
509 continue; 509 continue;
510 if (pciintr_bitmap_find_lowest_irq(l->bitmap & pciirq, 510 if (pciintr_bitmap_find_lowest_irq(l->bitmap & pciirq,
511 &l->irq)) { 511 &l->irq)) {
512 /* 512 /*
513 * This IRQ is a valid PCI IRQ already  513 * This IRQ is a valid PCI IRQ already
514 * connected to another PIRQ, and also an 514 * connected to another PIRQ, and also an
515 * IRQ our PIRQ can use; connect it up! 515 * IRQ our PIRQ can use; connect it up!
516 */ 516 */
517 l->fixup_stage = 2; 517 l->fixup_stage = 2;
518#ifdef PCIINTR_DEBUG 518#ifdef PCIINTR_DEBUG
519 printf("pciintr_link_fixup (stage 2): " 519 printf("pciintr_link_fixup (stage 2): "
520 "assigning IRQ %d to PIRQ 0x%02x\n", 520 "assigning IRQ %d to PIRQ 0x%02x\n",
521 l->irq, l->clink); 521 l->irq, l->clink);
522#endif 522#endif
523 } 523 }
524 } 524 }
525 525
526#ifdef PCIBIOS_IRQS_HINT 526#ifdef PCIBIOS_IRQS_HINT
527 /* 527 /*
528 * Stage 3: The worst case. I need configuration hint that 528 * Stage 3: The worst case. I need configuration hint that
529 * user supplied a mask for the PCI irqs 529 * user supplied a mask for the PCI irqs
530 */ 530 */
531 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 531 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
532 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) 532 if (l->irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
533 continue; 533 continue;
534 if (pciintr_bitmap_find_lowest_irq( 534 if (pciintr_bitmap_find_lowest_irq(
535 l->bitmap & pcibios_irqs_hint, &l->irq)) { 535 l->bitmap & pcibios_irqs_hint, &l->irq)) {
536 l->fixup_stage = 3; 536 l->fixup_stage = 3;
537#ifdef PCIINTR_DEBUG 537#ifdef PCIINTR_DEBUG
538 printf("pciintr_link_fixup (stage 3): " 538 printf("pciintr_link_fixup (stage 3): "
539 "assigning IRQ %d to PIRQ 0x%02x\n", 539 "assigning IRQ %d to PIRQ 0x%02x\n",
540 l->irq, l->clink); 540 l->irq, l->clink);
541#endif 541#endif
542 } 542 }
543 } 543 }
544#endif /* PCIBIOS_IRQS_HINT */ 544#endif /* PCIBIOS_IRQS_HINT */
545 545
546 return (0); 546 return (0);
547} 547}
548 548
549int 549int
550pciintr_link_route(uint16_t *pciirq) 550pciintr_link_route(uint16_t *pciirq)
551{ 551{
552 struct pciintr_link_map *l; 552 struct pciintr_link_map *l;
553 int rv = 0; 553 int rv = 0;
554 554
555 *pciirq = 0; 555 *pciirq = 0;
556 556
557 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) { 557 SIMPLEQ_FOREACH(l, &pciintr_link_map_list, list) {
558 if (l->fixup_stage == 0) { 558 if (l->fixup_stage == 0) {
559 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 559 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
560 /* Appropriate interrupt was not found. */ 560 /* Appropriate interrupt was not found. */
561#ifdef DIAGNOSTIC 561#ifdef DIAGNOSTIC
562 printf("pciintr_link_route: " 562 printf("pciintr_link_route: "
563 "PIRQ 0x%02x: no IRQ, try " 563 "PIRQ 0x%02x: no IRQ, try "
564 "\"options PCIBIOS_IRQS_HINT=0x%04x\"\n", 564 "\"options PCIBIOS_IRQS_HINT=0x%04x\"\n",
565 l->clink, 565 l->clink,
566 /* suggest irq 9/10/11, if possible */ 566 /* suggest irq 9/10/11, if possible */
567 (l->bitmap & 0x0e00) ? (l->bitmap & 0x0e00) 567 (l->bitmap & 0x0e00) ? (l->bitmap & 0x0e00)
568 : l->bitmap); 568 : l->bitmap);
569#endif 569#endif
570 } else { 570 } else {
571 /* BIOS setting has no problem */ 571 /* BIOS setting has no problem */
572#ifdef PCIINTR_DEBUG 572#ifdef PCIINTR_DEBUG
573 printf("pciintr_link_route: " 573 printf("pciintr_link_route: "
574 "route of PIRQ 0x%02x -> " 574 "route of PIRQ 0x%02x -> "
575 "IRQ %d preserved BIOS setting\n", 575 "IRQ %d preserved BIOS setting\n",
576 l->clink, l->irq); 576 l->clink, l->irq);
577#endif 577#endif
578 *pciirq |= (1 << l->irq); 578 *pciirq |= (1 << l->irq);
579 } 579 }
580 continue; /* nothing to do. */ 580 continue; /* nothing to do. */
581 } 581 }
582 582
583 if (pciintr_icu_set_intr(pciintr_icu_tag, pciintr_icu_handle, 583 if (pciintr_icu_set_intr(pciintr_icu_tag, pciintr_icu_handle,
584 l->clink, l->irq) != 0 || 584 l->clink, l->irq) != 0 ||
585 pciintr_icu_set_trigger(pciintr_icu_tag, 585 pciintr_icu_set_trigger(pciintr_icu_tag,
586 pciintr_icu_handle, 586 pciintr_icu_handle,
587 l->irq, IST_LEVEL) != 0) { 587 l->irq, IST_LEVEL) != 0) {
588 printf("pciintr_link_route: route of PIRQ 0x%02x -> " 588 printf("pciintr_link_route: route of PIRQ 0x%02x -> "
589 "IRQ %d failed\n", l->clink, l->irq); 589 "IRQ %d failed\n", l->clink, l->irq);
590 rv = 1; 590 rv = 1;
591 } else { 591 } else {
592 /* 592 /*
593 * Succssfully routed interrupt. Mark this as 593 * Succssfully routed interrupt. Mark this as
594 * a PCI interrupt. 594 * a PCI interrupt.
595 */ 595 */
596 *pciirq |= (1 << l->irq); 596 *pciirq |= (1 << l->irq);
597 } 597 }
598 } 598 }
599 599
600 return (rv); 600 return (rv);
601} 601}
602 602
603int 603int
604pciintr_irq_release(uint16_t *pciirq) 604pciintr_irq_release(uint16_t *pciirq)
605{ 605{
606 int i, bit; 606 int i, bit;
607 uint16_t bios_pciirq; 607 uint16_t bios_pciirq;
608 int reg; 608 int reg;
609 609
610#ifdef PCIINTR_DEBUG 610#ifdef PCIINTR_DEBUG
611 printf("pciintr_irq_release: fixup pciirq level/edge map 0x%04x\n", 611 printf("pciintr_irq_release: fixup pciirq level/edge map 0x%04x\n",
612 *pciirq); 612 *pciirq);
613#endif 613#endif
614 614
615 /* Get bios level/edge setting. */ 615 /* Get bios level/edge setting. */
616 bios_pciirq = 0; 616 bios_pciirq = 0;
617 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) { 617 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
618 (void)pciintr_icu_get_trigger(pciintr_icu_tag, 618 (void)pciintr_icu_get_trigger(pciintr_icu_tag,
619 pciintr_icu_handle, i, &reg); 619 pciintr_icu_handle, i, &reg);
620 if (reg == IST_LEVEL) 620 if (reg == IST_LEVEL)
621 bios_pciirq |= bit; 621 bios_pciirq |= bit;
622 } 622 }
623 623
624#ifdef PCIINTR_DEBUG 624#ifdef PCIINTR_DEBUG
625 printf("pciintr_irq_release: bios pciirq level/edge map 0x%04x\n", 625 printf("pciintr_irq_release: bios pciirq level/edge map 0x%04x\n",
626 bios_pciirq); 626 bios_pciirq);
627#endif /* PCIINTR_DEBUG */ 627#endif /* PCIINTR_DEBUG */
628 628
629 /* fixup final level/edge setting. */ 629 /* fixup final level/edge setting. */
630 *pciirq |= bios_pciirq; 630 *pciirq |= bios_pciirq;
631 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) { 631 for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
632 if ((*pciirq & bit) == 0) 632 if ((*pciirq & bit) == 0)
633 reg = IST_EDGE; 633 reg = IST_EDGE;
634 else 634 else
635 reg = IST_LEVEL; 635 reg = IST_LEVEL;
636 (void) pciintr_icu_set_trigger(pciintr_icu_tag, 636 (void) pciintr_icu_set_trigger(pciintr_icu_tag,
637 pciintr_icu_handle, i, reg); 637 pciintr_icu_handle, i, reg);
638 638
639 } 639 }
640 640
641#ifdef PCIINTR_DEBUG 641#ifdef PCIINTR_DEBUG
642 printf("pciintr_irq_release: final pciirq level/edge map 0x%04x\n", 642 printf("pciintr_irq_release: final pciirq level/edge map 0x%04x\n",
643 *pciirq); 643 *pciirq);
644#endif /* PCIINTR_DEBUG */ 644#endif /* PCIINTR_DEBUG */
645 645
646 return (0); 646 return (0);
647} 647}
648 648
649int 649int
650pciintr_header_fixup(pci_chipset_tag_t pc) 650pciintr_header_fixup(pci_chipset_tag_t pc)
651{ 651{
652 PCIBIOS_PRINTV(("------------------------------------------\n")); 652 PCIBIOS_PRINTV(("------------------------------------------\n"));
653 PCIBIOS_PRINTV((" device vendor product pin PIRQ IRQ stage\n")); 653 PCIBIOS_PRINTV((" device vendor product pin PIRQ IRQ stage\n"));
654 PCIBIOS_PRINTV(("------------------------------------------\n")); 654 PCIBIOS_PRINTV(("------------------------------------------\n"));
655 pci_device_foreach(pc, pcibios_max_bus, pciintr_do_header_fixup, NULL); 655 pci_device_foreach(pc, pcibios_max_bus, pciintr_do_header_fixup, NULL);
656 PCIBIOS_PRINTV(("------------------------------------------\n")); 656 PCIBIOS_PRINTV(("------------------------------------------\n"));
657 657
658 return (0); 658 return (0);
659} 659}
660 660
661void 661void
662pciintr_do_header_fixup(pci_chipset_tag_t pc, pcitag_t tag, 662pciintr_do_header_fixup(pci_chipset_tag_t pc, pcitag_t tag,
663 void *context) 663 void *context)
664{ 664{
665 struct pcibios_intr_routing *pir; 665 struct pcibios_intr_routing *pir;
666 struct pciintr_link_map *l; 666 struct pciintr_link_map *l;
667 int pin, irq, link; 667 int pin, irq, link;
668 int bus, device, function; 668 int bus, device, function;
669 pcireg_t intr, id; 669 pcireg_t intr, id;
670 670
671 pci_decompose_tag(pc, tag, &bus, &device, &function); 671 pci_decompose_tag(pc, tag, &bus, &device, &function);
672 id = pci_conf_read(pc, tag, PCI_ID_REG); 672 id = pci_conf_read(pc, tag, PCI_ID_REG);
673 673
674 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 674 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
675 pin = PCI_INTERRUPT_PIN(intr); 675 pin = PCI_INTERRUPT_PIN(intr);
676 irq = PCI_INTERRUPT_LINE(intr); 676 irq = PCI_INTERRUPT_LINE(intr);
677 677
678#if 0 678#if 0
679 if (pin == 0) { 679 if (pin == 0) {
680 /* 680 /*
681 * No interrupt used. 681 * No interrupt used.
682 */ 682 */
683 return; 683 return;
684 } 684 }
685#endif 685#endif
686 686
687 pir = pciintr_pir_lookup(bus, device); 687 pir = pciintr_pir_lookup(bus, device);
688 if (pir == NULL || (link = pir->linkmap[pin - 1].link) == 0) { 688 if (pir == NULL || (link = pir->linkmap[pin - 1].link) == 0) {
689 /* 689 /*
690 * Interrupt not connected; no 690 * Interrupt not connected; no
691 * need to change. 691 * need to change.
692 */ 692 */
693 return; 693 return;
694 } 694 }
695 695
696 l = pciintr_link_lookup(link); 696 l = pciintr_link_lookup(link);
697 if (l == NULL) { 697 if (l == NULL) {
698#ifdef PCIINTR_DEBUG 698#ifdef PCIINTR_DEBUG
699 /* 699 /*
700 * No link map entry. 700 * No link map entry.
701 * Probably pciintr_icu_getclink() or pciintr_icu_get_intr() 701 * Probably pciintr_icu_getclink() or pciintr_icu_get_intr()
702 * was failed. 702 * was failed.
703 */ 703 */
704 printf("pciintr_header_fixup: no entry for link 0x%02x " 704 printf("pciintr_header_fixup: no entry for link 0x%02x "
705 "(%d:%d:%d:%c)\n", link, bus, device, function, 705 "(%d:%d:%d:%c)\n", link, bus, device, function,
706 '@' + pin); 706 '@' + pin);
707#endif 707#endif
708 return; 708 return;
709 } 709 }
710 710
711#ifdef PCIBIOSVERBOSE 711#ifdef PCIBIOSVERBOSE
712 if (pcibiosverbose) { 712 if (pcibiosverbose) {
713 PCIBIOS_PRINTV(("%03d:%02d:%d 0x%04x 0x%04x %c 0x%02x", 713 PCIBIOS_PRINTV(("%03d:%02d:%d 0x%04x 0x%04x %c 0x%02x",
714 bus, device, function, PCI_VENDOR(id), PCI_PRODUCT(id), 714 bus, device, function, PCI_VENDOR(id), PCI_PRODUCT(id),
715 '@' + pin, l->clink)); 715 '@' + pin, l->clink));
716 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) 716 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
717 PCIBIOS_PRINTV((" -")); 717 PCIBIOS_PRINTV((" -"));
718 else 718 else
719 PCIBIOS_PRINTV((" %3d", l->irq)); 719 PCIBIOS_PRINTV((" %3d", l->irq));
720 PCIBIOS_PRINTV((" %d ", l->fixup_stage)); 720 PCIBIOS_PRINTV((" %d ", l->fixup_stage));
721 } 721 }
722#endif 722#endif
723  723
724 /* 724 /*
725 * IRQs 14 and 15 are reserved for PCI IDE interrupts; don't muck 725 * IRQs 14 and 15 are reserved for PCI IDE interrupts; don't muck
726 * with them. 726 * with them.
727 */ 727 */
728 if (irq == 14 || irq == 15) { 728 if (irq == 14 || irq == 15) {
729 PCIBIOS_PRINTV((" WARNING: ignored\n")); 729 PCIBIOS_PRINTV((" WARNING: ignored\n"));
730 return; 730 return;
731 } 731 }
732 732
733 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 733 if (l->irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
734 /* Appropriate interrupt was not found. */ 734 /* Appropriate interrupt was not found. */
735 if (pciintr_icu_tag == NULL && 735 if (pciintr_icu_tag == NULL &&
736 irq != 0 && irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 736 irq != 0 && irq != X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
737 /* 737 /*
738 * Do not print warning, 738 * Do not print warning,
739 * if no compatible PCI ICU found, 739 * if no compatible PCI ICU found,
740 * but the irq is already assigned by BIOS. 740 * but the irq is already assigned by BIOS.
741 */ 741 */
742 PCIBIOS_PRINTV(("\n")); 742 PCIBIOS_PRINTV(("\n"));
743 } else { 743 } else {
744 PCIBIOS_PRINTV((" WARNING: missing IRQ\n")); 744 PCIBIOS_PRINTV((" WARNING: missing IRQ\n"));
745 } 745 }
746 return; 746 return;
747 } 747 }
748 748
749 if (l->irq == irq) { 749 if (l->irq == irq) {
750 /* don't have to reconfigure */ 750 /* don't have to reconfigure */
751 PCIBIOS_PRINTV((" already assigned\n")); 751 PCIBIOS_PRINTV((" already assigned\n"));
752 return; 752 return;
753 } 753 }
754 754
755 if (irq == 0 || irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 755 if (irq == 0 || irq == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) {
756 PCIBIOS_PRINTV((" fixed up\n")); 756 PCIBIOS_PRINTV((" fixed up\n"));
757 } else { 757 } else {
758 /* routed by BIOS, but inconsistent */ 758 /* routed by BIOS, but inconsistent */
759#ifdef PCI_INTR_FIXUP_FORCE 759#ifdef PCI_INTR_FIXUP_FORCE
760 /* believe PCI IRQ Routing table */ 760 /* believe PCI IRQ Routing table */
761 PCIBIOS_PRINTV((" WARNING: overriding irq %d\n", irq)); 761 PCIBIOS_PRINTV((" WARNING: overriding irq %d\n", irq));
762#else 762#else
763 /* believe PCI Interrupt Configuration Register (default) */ 763 /* believe PCI Interrupt Configuration Register (default) */
764 PCIBIOS_PRINTV((" WARNING: preserving irq %d\n", irq)); 764 PCIBIOS_PRINTV((" WARNING: preserving irq %d\n", irq));
765 return; 765 return;
766#endif 766#endif
767 } 767 }
768 768
769 intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT); 769 intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
770 intr |= (l->irq << PCI_INTERRUPT_LINE_SHIFT); 770 intr |= (l->irq << PCI_INTERRUPT_LINE_SHIFT);
771 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr); 771 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
772} 772}
773 773
774int 774int
775pci_intr_fixup(pci_chipset_tag_t pc, bus_space_tag_t iot, uint16_t *pciirq) 775pci_intr_fixup(pci_chipset_tag_t pc, bus_space_tag_t iot, uint16_t *pciirq)
776{ 776{
777 const struct pciintr_icu_table *piit = NULL; 777 const struct pciintr_icu_table *piit = NULL;
778 pcitag_t icutag; 778 pcitag_t icutag;
779 pcireg_t icuid; 779 pcireg_t icuid;
780 int error = 0; 780 int error = 0;
781 781
782 /* 782 /*
783 * Attempt to initialize our PCI interrupt router. If 783 * Attempt to initialize our PCI interrupt router. If
784 * the PIR Table is present in ROM, use the location 784 * the PIR Table is present in ROM, use the location
785 * specified by the PIR Table, and use the compat ID, 785 * specified by the PIR Table, and use the compat ID,
786 * if present. Otherwise, we have to look for the router 786 * if present. Otherwise, we have to look for the router
787 * ourselves (the PCI-ISA bridge). 787 * ourselves (the PCI-ISA bridge).
788 * 788 *
789 * A number of buggy BIOS implementations leave the router 789 * A number of buggy BIOS implementations leave the router
790 * entry as 000:00:0, which is typically not the correct 790 * entry as 000:00:0, which is typically not the correct
791 * device/function. If the router device address is set to 791 * device/function. If the router device address is set to
792 * this value, and the compatible router entry is undefined 792 * this value, and the compatible router entry is undefined
793 * (zero is the correct value to indicate undefined), then we 793 * (zero is the correct value to indicate undefined), then we
794 * work on the basis it is most likely an error, and search 794 * work on the basis it is most likely an error, and search
795 * the entire device-space of bus 0 (but obviously starting 795 * the entire device-space of bus 0 (but obviously starting
796 * with 000:00:0, in case that really is the right one). 796 * with 000:00:0, in case that really is the right one).
797 */ 797 */
798 if (pcibios_pir_header.signature != 0 && 798 if (pcibios_pir_header.signature != 0 &&
799 (pcibios_pir_header.router_bus != 0 || 799 (pcibios_pir_header.router_bus != 0 ||
800 PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc) != 0 || 800 PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc) != 0 ||
801 PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc) != 0 || 801 PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc) != 0 ||
802 pcibios_pir_header.compat_router != 0)) { 802 pcibios_pir_header.compat_router != 0)) {
803 icutag = pci_make_tag(pc, pcibios_pir_header.router_bus, 803 icutag = pci_make_tag(pc, pcibios_pir_header.router_bus,
804 PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc), 804 PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc),
805 PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc)); 805 PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc));
806 icuid = pci_conf_read(pc, icutag, PCI_ID_REG); 806 icuid = pci_conf_read(pc, icutag, PCI_ID_REG);
807 if ((piit = pciintr_icu_lookup(icuid)) == NULL) { 807 if ((piit = pciintr_icu_lookup(icuid)) == NULL) {
808 /* 808 /*
809 * if we fail to look up an ICU at given 809 * if we fail to look up an ICU at given
810 * PCI address, try compat ID next. 810 * PCI address, try compat ID next.
811 */ 811 */
812 icuid = pcibios_pir_header.compat_router; 812 icuid = pcibios_pir_header.compat_router;
813 piit = pciintr_icu_lookup(icuid); 813 piit = pciintr_icu_lookup(icuid);
814 } 814 }
815 } else { 815 } else {
816 int device, maxdevs = pci_bus_maxdevs(pc, 0); 816 int device, maxdevs = pci_bus_maxdevs(pc, 0);
817 817
818 /* 818 /*
819 * Search configuration space for a known interrupt 819 * Search configuration space for a known interrupt
820 * router. 820 * router.
821 */ 821 */
822 for (device = 0; device < maxdevs; device++) { 822 for (device = 0; device < maxdevs; device++) {
823 const struct pci_quirkdata *qd; 823 const struct pci_quirkdata *qd;
824 int function, nfuncs; 824 int function, nfuncs;
825 pcireg_t bhlcr; 825 pcireg_t bhlcr;
826 826
827 icutag = pci_make_tag(pc, 0, device, 0); 827 icutag = pci_make_tag(pc, 0, device, 0);
828 icuid = pci_conf_read(pc, icutag, PCI_ID_REG); 828 icuid = pci_conf_read(pc, icutag, PCI_ID_REG);
829 829
830 /* Invalid vendor ID value? */ 830 /* Invalid vendor ID value? */
831 if (PCI_VENDOR(icuid) == PCI_VENDOR_INVALID) 831 if (PCI_VENDOR(icuid) == PCI_VENDOR_INVALID)
832 continue; 832 continue;
833 /* XXX Not invalid, but we've done this ~forever. */ 833 /* XXX Not invalid, but we've done this ~forever. */
834 if (PCI_VENDOR(icuid) == 0) 834 if (PCI_VENDOR(icuid) == 0)
835 continue; 835 continue;
836 836
837 qd = pci_lookup_quirkdata(PCI_VENDOR(icuid), 837 qd = pci_lookup_quirkdata(PCI_VENDOR(icuid),
838 PCI_PRODUCT(icuid)); 838 PCI_PRODUCT(icuid));
839 839
840 bhlcr = pci_conf_read(pc, icutag, PCI_BHLC_REG); 840 bhlcr = pci_conf_read(pc, icutag, PCI_BHLC_REG);
841 if (PCI_HDRTYPE_MULTIFN(bhlcr) || 841 if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
842 (qd != NULL && 842 (qd != NULL &&
843 (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0)) 843 (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
844 nfuncs = 8; 844 nfuncs = 8;
845 else 845 else
846 nfuncs = 1; 846 nfuncs = 1;
847 847
848 for (function = 0; function < nfuncs; function++) { 848 for (function = 0; function < nfuncs; function++) {
849 icutag = pci_make_tag(pc, 0, device, function); 849 icutag = pci_make_tag(pc, 0, device, function);
850 icuid = pci_conf_read(pc, icutag, PCI_ID_REG); 850 icuid = pci_conf_read(pc, icutag, PCI_ID_REG);
851 851
852 /* Invalid vendor ID value? */ 852 /* Invalid vendor ID value? */
853 if (PCI_VENDOR(icuid) == PCI_VENDOR_INVALID) 853 if (PCI_VENDOR(icuid) == PCI_VENDOR_INVALID)
854 continue; 854 continue;
855 /* Not invalid, but we've done this ~forever */ 855 /* Not invalid, but we've done this ~forever */
856 if (PCI_VENDOR(icuid) == 0) 856 if (PCI_VENDOR(icuid) == 0)
857 continue; 857 continue;
858 858
859 piit = pciintr_icu_lookup(icuid); 859 piit = pciintr_icu_lookup(icuid);
860 if (piit != NULL) 860 if (piit != NULL)
861 goto found; 861 goto found;
862 } 862 }
863 } 863 }
864 864
865 /* 865 /*
866 * Invalidate the ICU ID. If we failed to find the 866 * Invalidate the ICU ID. If we failed to find the
867 * interrupt router (piit == NULL) we don't want to 867 * interrupt router (piit == NULL) we don't want to
868 * display a spurious device address below containing 868 * display a spurious device address below containing
869 * the product information of the last device we 869 * the product information of the last device we
870 * looked at. 870 * looked at.
871 */ 871 */
872 icuid = 0; 872 icuid = 0;
873found:; 873found:;
874 } 874 }
875 875
876 if (piit == NULL) { 876 if (piit == NULL) {
877 printf("pci_intr_fixup: no compatible PCI ICU found"); 877 printf("pci_intr_fixup: no compatible PCI ICU found");
878 if (pcibios_pir_header.signature != 0 && icuid != 0) 878 if (pcibios_pir_header.signature != 0 && icuid != 0)
879 printf(": ICU vendor 0x%04x product 0x%04x", 879 printf(": ICU vendor 0x%04x product 0x%04x",
880 PCI_VENDOR(icuid), PCI_PRODUCT(icuid)); 880 PCI_VENDOR(icuid), PCI_PRODUCT(icuid));
881 printf("\n"); 881 printf("\n");
882#ifdef PCIBIOS_INTR_GUESS 882#ifdef PCIBIOS_INTR_GUESS
883 if (pciintr_link_init()) 883 if (pciintr_link_init())
884 return (-1); /* non-fatal */ 884 return (-1); /* non-fatal */
885 if (pciintr_guess_irq()) 885 if (pciintr_guess_irq())
886 return (-1); /* non-fatal */ 886 return (-1); /* non-fatal */
887 if (pciintr_header_fixup(pc)) 887 if (pciintr_header_fixup(pc))
888 return (1); /* fatal */ 888 return (1); /* fatal */
889 return (0); /* success! */ 889 return (0); /* success! */
890#else 890#else
891 return (-1); /* non-fatal */ 891 return (-1); /* non-fatal */
892#endif 892#endif
893 } 893 }
894 894
895 /* 895 /*
896 * Initialize the PCI ICU. 896 * Initialize the PCI ICU.
897 */ 897 */
898 if ((*piit->piit_init)(pc, iot, icutag, &pciintr_icu_tag, 898 if ((*piit->piit_init)(pc, iot, icutag, &pciintr_icu_tag,
899 &pciintr_icu_handle) != 0) 899 &pciintr_icu_handle) != 0)
900 return (-1); /* non-fatal */ 900 return (-1); /* non-fatal */
901 901
902 /* 902 /*
903 * Initialize the PCI interrupt link map. 903 * Initialize the PCI interrupt link map.
904 */ 904 */
905 if (pciintr_link_init()) { 905 if (pciintr_link_init()) {
906 error = -1; /* non-fatal */ 906 error = -1; /* non-fatal */
907 goto cleanup; 907 goto cleanup;
908 } 908 }
909 909
910 /* 910 /*
911 * Fix up the link->IRQ mappings. 911 * Fix up the link->IRQ mappings.
912 */ 912 */
913 if (pciintr_link_fixup() != 0) { 913 if (pciintr_link_fixup() != 0) {
914 error = -1; /* non-fatal */ 914 error = -1; /* non-fatal */
915 goto cleanup; 915 goto cleanup;
916 } 916 }
917 917
918 /* 918 /*
919 * Now actually program the PCI ICU with the new 919 * Now actually program the PCI ICU with the new
920 * routing information. 920 * routing information.
921 */ 921 */
922 if (pciintr_link_route(pciirq) != 0) { 922 if (pciintr_link_route(pciirq) != 0) {
923 error = 1; /* fatal */ 923 error = 1; /* fatal */
924 goto cleanup; 924 goto cleanup;
925 } 925 }
926 926
927 /* 927 /*
928 * Now that we've routed all of the PIRQs, rewrite the PCI 928 * Now that we've routed all of the PIRQs, rewrite the PCI
929 * configuration headers to reflect the new mapping. 929 * configuration headers to reflect the new mapping.
930 */ 930 */
931 if (pciintr_header_fixup(pc) != 0) { 931 if (pciintr_header_fixup(pc) != 0) {
932 error = 1; /* fatal */ 932 error = 1; /* fatal */
933 goto cleanup; 933 goto cleanup;
934 } 934 }
935 935
936 /* 936 /*
937 * Free any unused PCI IRQs for ISA devices. 937 * Free any unused PCI IRQs for ISA devices.
938 */ 938 */
939 if (pciintr_irq_release(pciirq) != 0) { 939 if (pciintr_irq_release(pciirq) != 0) {
940 error = -1; /* non-fatal */ 940 error = -1; /* non-fatal */
941 goto cleanup; 941 goto cleanup;
942 } 942 }
943 943
944 /* 944 /*
945 * All done! 945 * All done!
946 */ 946 */
947cleanup: 947cleanup:
948 if (piit->piit_uninit != NULL) 948 if (piit->piit_uninit != NULL)
949 (*piit->piit_uninit)(pciintr_icu_handle); 949 (*piit->piit_uninit)(pciintr_icu_handle);
950 return (error); 950 return (error);
951} 951}

cvs diff -r1.29 -r1.30 src/sys/arch/x86/pci/ichlpcib.c (switch to unified diff)

--- src/sys/arch/x86/pci/ichlpcib.c 2011/04/04 20:37:55 1.29
+++ src/sys/arch/x86/pci/ichlpcib.c 2011/06/06 14:33:31 1.30
@@ -1,1283 +1,1283 @@ @@ -1,1283 +1,1283 @@
1/* $NetBSD: ichlpcib.c,v 1.29 2011/04/04 20:37:55 dyoung Exp $ */ 1/* $NetBSD: ichlpcib.c,v 1.30 2011/06/06 14:33:31 msaitoh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 4 * Copyright (c) 2004 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 Minoura Makoto and Matthew R. Green. 8 * by Minoura Makoto and Matthew R. Green.
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 * Intel I/O Controller Hub (ICHn) LPC Interface Bridge driver 33 * Intel I/O Controller Hub (ICHn) LPC Interface Bridge driver
34 * 34 *
35 * LPC Interface Bridge is basically a pcib (PCI-ISA Bridge), but has 35 * LPC Interface Bridge is basically a pcib (PCI-ISA Bridge), but has
36 * some power management and monitoring functions. 36 * some power management and monitoring functions.
37 * Currently we support the watchdog timer, SpeedStep (on some systems) 37 * Currently we support the watchdog timer, SpeedStep (on some systems)
38 * and the power management timer. 38 * and the power management timer.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.29 2011/04/04 20:37:55 dyoung Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.30 2011/06/06 14:33:31 msaitoh Exp $");
43 43
44#include <sys/types.h> 44#include <sys/types.h>
45#include <sys/param.h> 45#include <sys/param.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/sysctl.h> 48#include <sys/sysctl.h>
49#include <sys/timetc.h> 49#include <sys/timetc.h>
50#include <sys/gpio.h> 50#include <sys/gpio.h>
51#include <machine/bus.h> 51#include <machine/bus.h>
52 52
53#include <dev/pci/pcivar.h> 53#include <dev/pci/pcivar.h>
54#include <dev/pci/pcireg.h> 54#include <dev/pci/pcireg.h>
55#include <dev/pci/pcidevs.h> 55#include <dev/pci/pcidevs.h>
56 56
57#include <dev/gpio/gpiovar.h> 57#include <dev/gpio/gpiovar.h>
58#include <dev/sysmon/sysmonvar.h> 58#include <dev/sysmon/sysmonvar.h>
59 59
60#include <dev/ic/acpipmtimer.h> 60#include <dev/ic/acpipmtimer.h>
61#include <dev/ic/i82801lpcreg.h> 61#include <dev/ic/i82801lpcreg.h>
62#include <dev/ic/hpetreg.h> 62#include <dev/ic/hpetreg.h>
63#include <dev/ic/hpetvar.h> 63#include <dev/ic/hpetvar.h>
64 64
65#include "hpet.h" 65#include "hpet.h"
66#include "pcibvar.h" 66#include "pcibvar.h"
67#include "gpio.h" 67#include "gpio.h"
68#include "fwhrng.h" 68#include "fwhrng.h"
69 69
70#define LPCIB_GPIO_NPINS 64 70#define LPCIB_GPIO_NPINS 64
71 71
72struct lpcib_softc { 72struct lpcib_softc {
73 /* we call pcibattach() which assumes this starts like this: */ 73 /* we call pcibattach() which assumes this starts like this: */
74 struct pcib_softc sc_pcib; 74 struct pcib_softc sc_pcib;
75 75
76 struct pci_attach_args sc_pa; 76 struct pci_attach_args sc_pa;
77 int sc_has_rcba; 77 int sc_has_rcba;
78 int sc_has_ich5_hpet; 78 int sc_has_ich5_hpet;
79 79
80 /* RCBA */ 80 /* RCBA */
81 bus_space_tag_t sc_rcbat; 81 bus_space_tag_t sc_rcbat;
82 bus_space_handle_t sc_rcbah; 82 bus_space_handle_t sc_rcbah;
83 pcireg_t sc_rcba_reg; 83 pcireg_t sc_rcba_reg;
84 84
85 /* Watchdog variables. */ 85 /* Watchdog variables. */
86 struct sysmon_wdog sc_smw; 86 struct sysmon_wdog sc_smw;
87 bus_space_tag_t sc_iot; 87 bus_space_tag_t sc_iot;
88 bus_space_handle_t sc_ioh; 88 bus_space_handle_t sc_ioh;
89 bus_size_t sc_iosize; 89 bus_size_t sc_iosize;
90 90
91#if NHPET > 0 91#if NHPET > 0
92 /* HPET variables. */ 92 /* HPET variables. */
93 uint32_t sc_hpet_reg; 93 uint32_t sc_hpet_reg;
94#endif 94#endif
95 95
96#if NGPIO > 0 96#if NGPIO > 0
97 device_t sc_gpiobus; 97 device_t sc_gpiobus;
98 kmutex_t sc_gpio_mtx; 98 kmutex_t sc_gpio_mtx;
99 bus_space_tag_t sc_gpio_iot; 99 bus_space_tag_t sc_gpio_iot;
100 bus_space_handle_t sc_gpio_ioh; 100 bus_space_handle_t sc_gpio_ioh;
101 bus_size_t sc_gpio_ios; 101 bus_size_t sc_gpio_ios;
102 struct gpio_chipset_tag sc_gpio_gc; 102 struct gpio_chipset_tag sc_gpio_gc;
103 gpio_pin_t sc_gpio_pins[LPCIB_GPIO_NPINS]; 103 gpio_pin_t sc_gpio_pins[LPCIB_GPIO_NPINS];
104#endif 104#endif
105 105
106#if NFWHRNG > 0 106#if NFWHRNG > 0
107 device_t sc_fwhbus; 107 device_t sc_fwhbus;
108#endif 108#endif
109 109
110 /* Speedstep */ 110 /* Speedstep */
111 pcireg_t sc_pmcon_orig; 111 pcireg_t sc_pmcon_orig;
112 112
113 /* Power management */ 113 /* Power management */
114 pcireg_t sc_pirq[2]; 114 pcireg_t sc_pirq[2];
115 pcireg_t sc_pmcon; 115 pcireg_t sc_pmcon;
116 pcireg_t sc_fwhsel2; 116 pcireg_t sc_fwhsel2;
117 117
118 /* Child devices */ 118 /* Child devices */
119 device_t sc_hpetbus; 119 device_t sc_hpetbus;
120 acpipmtimer_t sc_pmtimer; 120 acpipmtimer_t sc_pmtimer;
121 pcireg_t sc_acpi_cntl; 121 pcireg_t sc_acpi_cntl;
122 122
123 struct sysctllog *sc_log; 123 struct sysctllog *sc_log;
124}; 124};
125 125
126static int lpcibmatch(device_t, cfdata_t, void *); 126static int lpcibmatch(device_t, cfdata_t, void *);
127static void lpcibattach(device_t, device_t, void *); 127static void lpcibattach(device_t, device_t, void *);
128static int lpcibdetach(device_t, int); 128static int lpcibdetach(device_t, int);
129static void lpcibchilddet(device_t, device_t); 129static void lpcibchilddet(device_t, device_t);
130static int lpcibrescan(device_t, const char *, const int *); 130static int lpcibrescan(device_t, const char *, const int *);
131static bool lpcib_suspend(device_t, const pmf_qual_t *); 131static bool lpcib_suspend(device_t, const pmf_qual_t *);
132static bool lpcib_resume(device_t, const pmf_qual_t *); 132static bool lpcib_resume(device_t, const pmf_qual_t *);
133static bool lpcib_shutdown(device_t, int); 133static bool lpcib_shutdown(device_t, int);
134 134
135static void pmtimer_configure(device_t); 135static void pmtimer_configure(device_t);
136static int pmtimer_unconfigure(device_t, int); 136static int pmtimer_unconfigure(device_t, int);
137 137
138static void tcotimer_configure(device_t); 138static void tcotimer_configure(device_t);
139static int tcotimer_unconfigure(device_t, int); 139static int tcotimer_unconfigure(device_t, int);
140static int tcotimer_setmode(struct sysmon_wdog *); 140static int tcotimer_setmode(struct sysmon_wdog *);
141static int tcotimer_tickle(struct sysmon_wdog *); 141static int tcotimer_tickle(struct sysmon_wdog *);
142static void tcotimer_stop(struct lpcib_softc *); 142static void tcotimer_stop(struct lpcib_softc *);
143static void tcotimer_start(struct lpcib_softc *); 143static void tcotimer_start(struct lpcib_softc *);
144static void tcotimer_status_reset(struct lpcib_softc *); 144static void tcotimer_status_reset(struct lpcib_softc *);
145static int tcotimer_disable_noreboot(device_t); 145static int tcotimer_disable_noreboot(device_t);
146 146
147static void speedstep_configure(device_t); 147static void speedstep_configure(device_t);
148static void speedstep_unconfigure(device_t); 148static void speedstep_unconfigure(device_t);
149static int speedstep_sysctl_helper(SYSCTLFN_ARGS); 149static int speedstep_sysctl_helper(SYSCTLFN_ARGS);
150 150
151#if NHPET > 0 151#if NHPET > 0
152static void lpcib_hpet_configure(device_t); 152static void lpcib_hpet_configure(device_t);
153static int lpcib_hpet_unconfigure(device_t, int); 153static int lpcib_hpet_unconfigure(device_t, int);
154#endif 154#endif
155 155
156#if NGPIO > 0 156#if NGPIO > 0
157static void lpcib_gpio_configure(device_t); 157static void lpcib_gpio_configure(device_t);
158static int lpcib_gpio_unconfigure(device_t, int); 158static int lpcib_gpio_unconfigure(device_t, int);
159static int lpcib_gpio_pin_read(void *, int); 159static int lpcib_gpio_pin_read(void *, int);
160static void lpcib_gpio_pin_write(void *, int, int); 160static void lpcib_gpio_pin_write(void *, int, int);
161static void lpcib_gpio_pin_ctl(void *, int, int); 161static void lpcib_gpio_pin_ctl(void *, int, int);
162#endif 162#endif
163 163
164#if NFWHRNG > 0 164#if NFWHRNG > 0
165static void lpcib_fwh_configure(device_t); 165static void lpcib_fwh_configure(device_t);
166static int lpcib_fwh_unconfigure(device_t, int); 166static int lpcib_fwh_unconfigure(device_t, int);
167#endif 167#endif
168 168
169struct lpcib_softc *speedstep_cookie; /* XXX */ 169struct lpcib_softc *speedstep_cookie; /* XXX */
170 170
171CFATTACH_DECL2_NEW(ichlpcib, sizeof(struct lpcib_softc), 171CFATTACH_DECL2_NEW(ichlpcib, sizeof(struct lpcib_softc),
172 lpcibmatch, lpcibattach, lpcibdetach, NULL, lpcibrescan, lpcibchilddet); 172 lpcibmatch, lpcibattach, lpcibdetach, NULL, lpcibrescan, lpcibchilddet);
173 173
174static struct lpcib_device { 174static struct lpcib_device {
175 pcireg_t vendor, product; 175 pcireg_t vendor, product;
176 int has_rcba; 176 int has_rcba;
177 int has_ich5_hpet; 177 int has_ich5_hpet;
178} lpcib_devices[] = { 178} lpcib_devices[] = {
179 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 0, 0 }, 179 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 0, 0 },
180 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC, 0, 0 }, 180 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC, 0, 0 },
181 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 0, 0 }, 181 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 0, 0 },
182 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 0, 0 }, 182 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 0, 0 },
183 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, 0 }, 183 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, 0 },
184 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 0, 0 }, 184 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 0, 0 },
185 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 0, 0 }, 185 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 0, 0 },
186 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_ISA, 0, 0 }, 186 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DBM_LPC, 0, 0 },
187 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC, 0, 1 }, 187 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC, 0, 1 },
188 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC, 1, 0 }, 188 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC, 1, 0 },
189 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC, 1, 0 }, 189 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC, 1, 0 },
190 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC, 1, 0 }, 190 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC, 1, 0 },
191 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC, 1, 0 }, 191 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC, 1, 0 },
192 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 1, 0 }, 192 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 1, 0 },
193 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC, 1, 0 }, 193 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC, 1, 0 },
194 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC, 1, 0 }, 194 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC, 1, 0 },
195 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HH_LPC, 1, 0 }, 195 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HH_LPC, 1, 0 },
196 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HO_LPC, 1, 0 }, 196 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HO_LPC, 1, 0 },
197 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC, 1, 0 }, 197 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC, 1, 0 },
198 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IH_LPC, 1, 0 }, 198 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IH_LPC, 1, 0 },
199 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IO_LPC, 1, 0 }, 199 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IO_LPC, 1, 0 },
200 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC, 1, 0 }, 200 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC, 1, 0 },
201 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC, 1, 0 }, 201 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC, 1, 0 },
202 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IB_LPC, 1, 0 }, 202 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IB_LPC, 1, 0 },
203 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_63XXESB_LPC, 1, 0 },  203 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_63XXESB_LPC, 1, 0 },
204 204
205 { 0, 0, 0, 0 }, 205 { 0, 0, 0, 0 },
206}; 206};
207 207
208/* 208/*
209 * Autoconf callbacks. 209 * Autoconf callbacks.
210 */ 210 */
211static int 211static int
212lpcibmatch(device_t parent, cfdata_t match, void *aux) 212lpcibmatch(device_t parent, cfdata_t match, void *aux)
213{ 213{
214 struct pci_attach_args *pa = aux; 214 struct pci_attach_args *pa = aux;
215 struct lpcib_device *lpcib_dev; 215 struct lpcib_device *lpcib_dev;
216 216
217 /* We are ISA bridge, of course */ 217 /* We are ISA bridge, of course */
218 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE || 218 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE ||
219 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) 219 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA)
220 return 0; 220 return 0;
221 221
222 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 222 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) {
223 if (PCI_VENDOR(pa->pa_id) == lpcib_dev->vendor && 223 if (PCI_VENDOR(pa->pa_id) == lpcib_dev->vendor &&
224 PCI_PRODUCT(pa->pa_id) == lpcib_dev->product) 224 PCI_PRODUCT(pa->pa_id) == lpcib_dev->product)
225 return 10; 225 return 10;
226 } 226 }
227 227
228 return 0; 228 return 0;
229} 229}
230 230
231static void 231static void
232lpcibattach(device_t parent, device_t self, void *aux) 232lpcibattach(device_t parent, device_t self, void *aux)
233{ 233{
234 struct pci_attach_args *pa = aux; 234 struct pci_attach_args *pa = aux;
235 struct lpcib_softc *sc = device_private(self); 235 struct lpcib_softc *sc = device_private(self);
236 struct lpcib_device *lpcib_dev; 236 struct lpcib_device *lpcib_dev;
237 237
238 sc->sc_pa = *pa; 238 sc->sc_pa = *pa;
239 239
240 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 240 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) {
241 if (PCI_VENDOR(pa->pa_id) != lpcib_dev->vendor || 241 if (PCI_VENDOR(pa->pa_id) != lpcib_dev->vendor ||
242 PCI_PRODUCT(pa->pa_id) != lpcib_dev->product) 242 PCI_PRODUCT(pa->pa_id) != lpcib_dev->product)
243 continue; 243 continue;
244 sc->sc_has_rcba = lpcib_dev->has_rcba; 244 sc->sc_has_rcba = lpcib_dev->has_rcba;
245 sc->sc_has_ich5_hpet = lpcib_dev->has_ich5_hpet; 245 sc->sc_has_ich5_hpet = lpcib_dev->has_ich5_hpet;
246 break; 246 break;
247 } 247 }
248 248
249 pcibattach(parent, self, aux); 249 pcibattach(parent, self, aux);
250 250
251 /* 251 /*
252 * Part of our I/O registers are used as ACPI PM regs. 252 * Part of our I/O registers are used as ACPI PM regs.
253 * Since our ACPI subsystem accesses the I/O space directly so far, 253 * Since our ACPI subsystem accesses the I/O space directly so far,
254 * we do not have to bother bus_space I/O map confliction. 254 * we do not have to bother bus_space I/O map confliction.
255 */ 255 */
256 if (pci_mapreg_map(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0, 256 if (pci_mapreg_map(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0,
257 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) { 257 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
258 aprint_error_dev(self, "can't map power management i/o space"); 258 aprint_error_dev(self, "can't map power management i/o space");
259 return; 259 return;
260 } 260 }
261 261
262 sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 262 sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
263 LPCIB_PCI_GEN_PMCON_1); 263 LPCIB_PCI_GEN_PMCON_1);
264 264
265 /* For ICH6 and later, always enable RCBA */ 265 /* For ICH6 and later, always enable RCBA */
266 if (sc->sc_has_rcba) { 266 if (sc->sc_has_rcba) {
267 pcireg_t rcba; 267 pcireg_t rcba;
268 268
269 sc->sc_rcbat = sc->sc_pa.pa_memt; 269 sc->sc_rcbat = sc->sc_pa.pa_memt;
270 270
271 rcba = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 271 rcba = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
272 LPCIB_RCBA); 272 LPCIB_RCBA);
273 if ((rcba & LPCIB_RCBA_EN) == 0) { 273 if ((rcba & LPCIB_RCBA_EN) == 0) {
274 aprint_error_dev(self, "RCBA is not enabled"); 274 aprint_error_dev(self, "RCBA is not enabled");
275 return; 275 return;
276 } 276 }
277 rcba &= ~LPCIB_RCBA_EN; 277 rcba &= ~LPCIB_RCBA_EN;
278 278
279 if (bus_space_map(sc->sc_rcbat, rcba, LPCIB_RCBA_SIZE, 0, 279 if (bus_space_map(sc->sc_rcbat, rcba, LPCIB_RCBA_SIZE, 0,
280 &sc->sc_rcbah)) { 280 &sc->sc_rcbah)) {
281 aprint_error_dev(self, "RCBA could not be mapped"); 281 aprint_error_dev(self, "RCBA could not be mapped");
282 return; 282 return;
283 } 283 }
284 } 284 }
285 285
286 /* Set up the power management timer. */ 286 /* Set up the power management timer. */
287 pmtimer_configure(self); 287 pmtimer_configure(self);
288 288
289 /* Set up the TCO (watchdog). */ 289 /* Set up the TCO (watchdog). */
290 tcotimer_configure(self); 290 tcotimer_configure(self);
291 291
292 /* Set up SpeedStep. */ 292 /* Set up SpeedStep. */
293 speedstep_configure(self); 293 speedstep_configure(self);
294 294
295#if NHPET > 0 295#if NHPET > 0
296 /* Set up HPET. */ 296 /* Set up HPET. */
297 lpcib_hpet_configure(self); 297 lpcib_hpet_configure(self);
298#endif 298#endif
299 299
300#if NGPIO > 0 300#if NGPIO > 0
301 /* Set up GPIO */ 301 /* Set up GPIO */
302 lpcib_gpio_configure(self); 302 lpcib_gpio_configure(self);
303#endif 303#endif
304 304
305#if NFWHRNG > 0 305#if NFWHRNG > 0
306 lpcib_fwh_configure(self); 306 lpcib_fwh_configure(self);
307#endif 307#endif
308 308
309 /* Install power handler */ 309 /* Install power handler */
310 if (!pmf_device_register1(self, lpcib_suspend, lpcib_resume, 310 if (!pmf_device_register1(self, lpcib_suspend, lpcib_resume,
311 lpcib_shutdown)) 311 lpcib_shutdown))
312 aprint_error_dev(self, "couldn't establish power handler\n"); 312 aprint_error_dev(self, "couldn't establish power handler\n");
313} 313}
314 314
315static void 315static void
316lpcibchilddet(device_t self, device_t child) 316lpcibchilddet(device_t self, device_t child)
317{ 317{
318 struct lpcib_softc *sc = device_private(self); 318 struct lpcib_softc *sc = device_private(self);
319 uint32_t val; 319 uint32_t val;
320 320
321#if NFWHRNG > 0 321#if NFWHRNG > 0
322 if (sc->sc_fwhbus == child) { 322 if (sc->sc_fwhbus == child) {
323 sc->sc_fwhbus = NULL; 323 sc->sc_fwhbus = NULL;
324 return; 324 return;
325 } 325 }
326#endif 326#endif
327#if NGPIO > 0 327#if NGPIO > 0
328 if (sc->sc_gpiobus == child) { 328 if (sc->sc_gpiobus == child) {
329 sc->sc_gpiobus = NULL; 329 sc->sc_gpiobus = NULL;
330 return; 330 return;
331 } 331 }
332#endif 332#endif
333 if (sc->sc_hpetbus != child) { 333 if (sc->sc_hpetbus != child) {
334 pcibchilddet(self, child); 334 pcibchilddet(self, child);
335 return; 335 return;
336 } 336 }
337 sc->sc_hpetbus = NULL; 337 sc->sc_hpetbus = NULL;
338 if (sc->sc_has_ich5_hpet) { 338 if (sc->sc_has_ich5_hpet) {
339 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 339 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
340 LPCIB_PCI_GEN_CNTL); 340 LPCIB_PCI_GEN_CNTL);
341 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 341 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) {
342 case LPCIB_ICH5_HPTC_0000: 342 case LPCIB_ICH5_HPTC_0000:
343 case LPCIB_ICH5_HPTC_1000: 343 case LPCIB_ICH5_HPTC_1000:
344 case LPCIB_ICH5_HPTC_2000: 344 case LPCIB_ICH5_HPTC_2000:
345 case LPCIB_ICH5_HPTC_3000: 345 case LPCIB_ICH5_HPTC_3000:
346 break; 346 break;
347 default: 347 default:
348 return; 348 return;
349 } 349 }
350 val &= ~LPCIB_ICH5_HPTC_EN; 350 val &= ~LPCIB_ICH5_HPTC_EN;
351 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 351 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
352 LPCIB_PCI_GEN_CNTL, val); 352 LPCIB_PCI_GEN_CNTL, val);
353 } else if (sc->sc_has_rcba) { 353 } else if (sc->sc_has_rcba) {
354 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 354 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
355 LPCIB_RCBA_HPTC); 355 LPCIB_RCBA_HPTC);
356 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 356 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) {
357 case LPCIB_RCBA_HPTC_0000: 357 case LPCIB_RCBA_HPTC_0000:
358 case LPCIB_RCBA_HPTC_1000: 358 case LPCIB_RCBA_HPTC_1000:
359 case LPCIB_RCBA_HPTC_2000: 359 case LPCIB_RCBA_HPTC_2000:
360 case LPCIB_RCBA_HPTC_3000: 360 case LPCIB_RCBA_HPTC_3000:
361 break; 361 break;
362 default: 362 default:
363 return; 363 return;
364 } 364 }
365 val &= ~LPCIB_RCBA_HPTC_EN; 365 val &= ~LPCIB_RCBA_HPTC_EN;
366 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 366 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
367 val); 367 val);
368 } 368 }
369} 369}
370 370
371static int 371static int
372lpcibrescan(device_t self, const char *ifattr, const int *locators) 372lpcibrescan(device_t self, const char *ifattr, const int *locators)
373{ 373{
374#if NHPET > 0 || NGPIO > 0 || NFWHRNG > 0 374#if NHPET > 0 || NGPIO > 0 || NFWHRNG > 0
375 struct lpcib_softc *sc = device_private(self); 375 struct lpcib_softc *sc = device_private(self);
376#endif 376#endif
377 377
378#if NFWHRNG > 0 378#if NFWHRNG > 0
379 if (ifattr_match(ifattr, "fwhichbus") && sc->sc_fwhbus == NULL) 379 if (ifattr_match(ifattr, "fwhichbus") && sc->sc_fwhbus == NULL)
380 lpcib_fwh_configure(self); 380 lpcib_fwh_configure(self);
381#endif 381#endif
382 382
383#if NHPET > 0 383#if NHPET > 0
384 if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL) 384 if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL)
385 lpcib_hpet_configure(self); 385 lpcib_hpet_configure(self);
386#endif 386#endif
387 387
388#if NGPIO > 0 388#if NGPIO > 0
389 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpiobus == NULL) 389 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpiobus == NULL)
390 lpcib_gpio_configure(self); 390 lpcib_gpio_configure(self);
391#endif 391#endif
392 392
393 return pcibrescan(self, ifattr, locators); 393 return pcibrescan(self, ifattr, locators);
394} 394}
395 395
396static int 396static int
397lpcibdetach(device_t self, int flags) 397lpcibdetach(device_t self, int flags)
398{ 398{
399 struct lpcib_softc *sc = device_private(self); 399 struct lpcib_softc *sc = device_private(self);
400 int rc; 400 int rc;
401 401
402 pmf_device_deregister(self); 402 pmf_device_deregister(self);
403 403
404#if NFWHRNG > 0 404#if NFWHRNG > 0
405 if ((rc = lpcib_fwh_unconfigure(self, flags)) != 0) 405 if ((rc = lpcib_fwh_unconfigure(self, flags)) != 0)
406 return rc; 406 return rc;
407#endif 407#endif
408 408
409#if NHPET > 0 409#if NHPET > 0
410 if ((rc = lpcib_hpet_unconfigure(self, flags)) != 0) 410 if ((rc = lpcib_hpet_unconfigure(self, flags)) != 0)
411 return rc; 411 return rc;
412#endif 412#endif
413 413
414#if NGPIO > 0 414#if NGPIO > 0
415 if ((rc = lpcib_gpio_unconfigure(self, flags)) != 0) 415 if ((rc = lpcib_gpio_unconfigure(self, flags)) != 0)
416 return rc; 416 return rc;
417#endif 417#endif
418 418
419 /* Set up SpeedStep. */ 419 /* Set up SpeedStep. */
420 speedstep_unconfigure(self); 420 speedstep_unconfigure(self);
421 421
422 if ((rc = tcotimer_unconfigure(self, flags)) != 0) 422 if ((rc = tcotimer_unconfigure(self, flags)) != 0)
423 return rc; 423 return rc;
424 424
425 if ((rc = pmtimer_unconfigure(self, flags)) != 0) 425 if ((rc = pmtimer_unconfigure(self, flags)) != 0)
426 return rc; 426 return rc;
427 427
428 if (sc->sc_has_rcba) 428 if (sc->sc_has_rcba)
429 bus_space_unmap(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_SIZE); 429 bus_space_unmap(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_SIZE);
430 430
431 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 431 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize);
432 432
433 return pcibdetach(self, flags); 433 return pcibdetach(self, flags);
434} 434}
435 435
436static bool 436static bool
437lpcib_shutdown(device_t dv, int howto) 437lpcib_shutdown(device_t dv, int howto)
438{ 438{
439 struct lpcib_softc *sc = device_private(dv); 439 struct lpcib_softc *sc = device_private(dv);
440 440
441 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 441 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
442 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 442 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig);
443 443
444 return true; 444 return true;
445} 445}
446 446
447static bool 447static bool
448lpcib_suspend(device_t dv, const pmf_qual_t *qual) 448lpcib_suspend(device_t dv, const pmf_qual_t *qual)
449{ 449{
450 struct lpcib_softc *sc = device_private(dv); 450 struct lpcib_softc *sc = device_private(dv);
451 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 451 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc;
452 pcitag_t tag = sc->sc_pcib.sc_tag; 452 pcitag_t tag = sc->sc_pcib.sc_tag;
453 453
454 /* capture PIRQ routing control registers */ 454 /* capture PIRQ routing control registers */
455 sc->sc_pirq[0] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQA_ROUT); 455 sc->sc_pirq[0] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQA_ROUT);
456 sc->sc_pirq[1] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQE_ROUT); 456 sc->sc_pirq[1] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQE_ROUT);
457 457
458 sc->sc_pmcon = pci_conf_read(pc, tag, LPCIB_PCI_GEN_PMCON_1); 458 sc->sc_pmcon = pci_conf_read(pc, tag, LPCIB_PCI_GEN_PMCON_1);
459 sc->sc_fwhsel2 = pci_conf_read(pc, tag, LPCIB_PCI_GEN_STA); 459 sc->sc_fwhsel2 = pci_conf_read(pc, tag, LPCIB_PCI_GEN_STA);
460 460
461 if (sc->sc_has_rcba) { 461 if (sc->sc_has_rcba) {
462 sc->sc_rcba_reg = pci_conf_read(pc, tag, LPCIB_RCBA); 462 sc->sc_rcba_reg = pci_conf_read(pc, tag, LPCIB_RCBA);
463#if NHPET > 0 463#if NHPET > 0
464 sc->sc_hpet_reg = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 464 sc->sc_hpet_reg = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
465 LPCIB_RCBA_HPTC); 465 LPCIB_RCBA_HPTC);
466#endif 466#endif
467 } else if (sc->sc_has_ich5_hpet) { 467 } else if (sc->sc_has_ich5_hpet) {
468#if NHPET > 0 468#if NHPET > 0
469 sc->sc_hpet_reg = pci_conf_read(pc, tag, LPCIB_PCI_GEN_CNTL); 469 sc->sc_hpet_reg = pci_conf_read(pc, tag, LPCIB_PCI_GEN_CNTL);
470#endif 470#endif
471 } 471 }
472 472
473 return true; 473 return true;
474} 474}
475 475
476static bool 476static bool
477lpcib_resume(device_t dv, const pmf_qual_t *qual) 477lpcib_resume(device_t dv, const pmf_qual_t *qual)
478{ 478{
479 struct lpcib_softc *sc = device_private(dv); 479 struct lpcib_softc *sc = device_private(dv);
480 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 480 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc;
481 pcitag_t tag = sc->sc_pcib.sc_tag; 481 pcitag_t tag = sc->sc_pcib.sc_tag;
482 482
483 /* restore PIRQ routing control registers */ 483 /* restore PIRQ routing control registers */
484 pci_conf_write(pc, tag, LPCIB_PCI_PIRQA_ROUT, sc->sc_pirq[0]); 484 pci_conf_write(pc, tag, LPCIB_PCI_PIRQA_ROUT, sc->sc_pirq[0]);
485 pci_conf_write(pc, tag, LPCIB_PCI_PIRQE_ROUT, sc->sc_pirq[1]); 485 pci_conf_write(pc, tag, LPCIB_PCI_PIRQE_ROUT, sc->sc_pirq[1]);
486 486
487 pci_conf_write(pc, tag, LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon); 487 pci_conf_write(pc, tag, LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon);
488 pci_conf_write(pc, tag, LPCIB_PCI_GEN_STA, sc->sc_fwhsel2); 488 pci_conf_write(pc, tag, LPCIB_PCI_GEN_STA, sc->sc_fwhsel2);
489 489
490 if (sc->sc_has_rcba) { 490 if (sc->sc_has_rcba) {
491 pci_conf_write(pc, tag, LPCIB_RCBA, sc->sc_rcba_reg); 491 pci_conf_write(pc, tag, LPCIB_RCBA, sc->sc_rcba_reg);
492#if NHPET > 0 492#if NHPET > 0
493 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 493 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
494 sc->sc_hpet_reg); 494 sc->sc_hpet_reg);
495#endif 495#endif
496 } else if (sc->sc_has_ich5_hpet) { 496 } else if (sc->sc_has_ich5_hpet) {
497#if NHPET > 0 497#if NHPET > 0
498 pci_conf_write(pc, tag, LPCIB_PCI_GEN_CNTL, sc->sc_hpet_reg); 498 pci_conf_write(pc, tag, LPCIB_PCI_GEN_CNTL, sc->sc_hpet_reg);
499#endif 499#endif
500 } 500 }
501 501
502 return true; 502 return true;
503} 503}
504 504
505/* 505/*
506 * Initialize the power management timer. 506 * Initialize the power management timer.
507 */ 507 */
508static void 508static void
509pmtimer_configure(device_t self) 509pmtimer_configure(device_t self)
510{ 510{
511 struct lpcib_softc *sc = device_private(self); 511 struct lpcib_softc *sc = device_private(self);
512 pcireg_t control; 512 pcireg_t control;
513 513
514 /*  514 /*
515 * Check if power management I/O space is enabled and enable the ACPI_EN 515 * Check if power management I/O space is enabled and enable the ACPI_EN
516 * bit if it's disabled. 516 * bit if it's disabled.
517 */ 517 */
518 control = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 518 control = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
519 LPCIB_PCI_ACPI_CNTL); 519 LPCIB_PCI_ACPI_CNTL);
520 sc->sc_acpi_cntl = control; 520 sc->sc_acpi_cntl = control;
521 if ((control & LPCIB_PCI_ACPI_CNTL_EN) == 0) { 521 if ((control & LPCIB_PCI_ACPI_CNTL_EN) == 0) {
522 control |= LPCIB_PCI_ACPI_CNTL_EN; 522 control |= LPCIB_PCI_ACPI_CNTL_EN;
523 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 523 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
524 LPCIB_PCI_ACPI_CNTL, control); 524 LPCIB_PCI_ACPI_CNTL, control);
525 } 525 }
526 526
527 /* Attach our PM timer with the generic acpipmtimer function */ 527 /* Attach our PM timer with the generic acpipmtimer function */
528 sc->sc_pmtimer = acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh, 528 sc->sc_pmtimer = acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh,
529 LPCIB_PM1_TMR, 0); 529 LPCIB_PM1_TMR, 0);
530} 530}
531 531
532static int 532static int
533pmtimer_unconfigure(device_t self, int flags) 533pmtimer_unconfigure(device_t self, int flags)
534{ 534{
535 struct lpcib_softc *sc = device_private(self); 535 struct lpcib_softc *sc = device_private(self);
536 int rc; 536 int rc;
537 537
538 if (sc->sc_pmtimer != NULL && 538 if (sc->sc_pmtimer != NULL &&
539 (rc = acpipmtimer_detach(sc->sc_pmtimer, flags)) != 0) 539 (rc = acpipmtimer_detach(sc->sc_pmtimer, flags)) != 0)
540 return rc; 540 return rc;
541 541
542 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 542 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
543 LPCIB_PCI_ACPI_CNTL, sc->sc_acpi_cntl); 543 LPCIB_PCI_ACPI_CNTL, sc->sc_acpi_cntl);
544 544
545 return 0; 545 return 0;
546} 546}
547 547
548/* 548/*
549 * Initialize the watchdog timer. 549 * Initialize the watchdog timer.
550 */ 550 */
551static void 551static void
552tcotimer_configure(device_t self) 552tcotimer_configure(device_t self)
553{ 553{
554 struct lpcib_softc *sc = device_private(self); 554 struct lpcib_softc *sc = device_private(self);
555 uint32_t ioreg; 555 uint32_t ioreg;
556 unsigned int period; 556 unsigned int period;
557 557
558 /* Explicitly stop the TCO timer. */ 558 /* Explicitly stop the TCO timer. */
559 tcotimer_stop(sc); 559 tcotimer_stop(sc);
560 560
561 /* 561 /*
562 * Enable TCO timeout SMI only if the hardware reset does not 562 * Enable TCO timeout SMI only if the hardware reset does not
563 * work. We don't know what the SMBIOS does. 563 * work. We don't know what the SMBIOS does.
564 */ 564 */
565 ioreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN); 565 ioreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN);
566 ioreg &= ~LPCIB_SMI_EN_TCO_EN; 566 ioreg &= ~LPCIB_SMI_EN_TCO_EN;
567 567
568 /*  568 /*
569 * Clear the No Reboot (NR) bit. If this fails, enabling the TCO_EN bit 569 * Clear the No Reboot (NR) bit. If this fails, enabling the TCO_EN bit
570 * in the SMI_EN register is the last chance. 570 * in the SMI_EN register is the last chance.
571 */ 571 */
572 if (tcotimer_disable_noreboot(self)) { 572 if (tcotimer_disable_noreboot(self)) {
573 ioreg |= LPCIB_SMI_EN_TCO_EN; 573 ioreg |= LPCIB_SMI_EN_TCO_EN;
574 } 574 }
575 if ((ioreg & LPCIB_SMI_EN_GBL_SMI_EN) != 0) { 575 if ((ioreg & LPCIB_SMI_EN_GBL_SMI_EN) != 0) {
576 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN, ioreg); 576 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN, ioreg);
577 } 577 }
578 578
579 /* Reset the watchdog status registers. */ 579 /* Reset the watchdog status registers. */
580 tcotimer_status_reset(sc); 580 tcotimer_status_reset(sc);
581 581
582 /*  582 /*
583 * Register the driver with the sysmon watchdog framework. 583 * Register the driver with the sysmon watchdog framework.
584 */ 584 */
585 sc->sc_smw.smw_name = device_xname(self); 585 sc->sc_smw.smw_name = device_xname(self);
586 sc->sc_smw.smw_cookie = sc; 586 sc->sc_smw.smw_cookie = sc;
587 sc->sc_smw.smw_setmode = tcotimer_setmode; 587 sc->sc_smw.smw_setmode = tcotimer_setmode;
588 sc->sc_smw.smw_tickle = tcotimer_tickle; 588 sc->sc_smw.smw_tickle = tcotimer_tickle;
589 if (sc->sc_has_rcba) 589 if (sc->sc_has_rcba)
590 period = LPCIB_TCOTIMER2_MAX_TICK; 590 period = LPCIB_TCOTIMER2_MAX_TICK;
591 else 591 else
592 period = LPCIB_TCOTIMER_MAX_TICK; 592 period = LPCIB_TCOTIMER_MAX_TICK;
593 sc->sc_smw.smw_period = lpcib_tcotimer_tick_to_second(period); 593 sc->sc_smw.smw_period = lpcib_tcotimer_tick_to_second(period);
594 594
595 if (sysmon_wdog_register(&sc->sc_smw)) { 595 if (sysmon_wdog_register(&sc->sc_smw)) {
596 aprint_error_dev(self, "unable to register TCO timer" 596 aprint_error_dev(self, "unable to register TCO timer"
597 "as a sysmon watchdog device.\n"); 597 "as a sysmon watchdog device.\n");
598 return; 598 return;
599 } 599 }
600 600
601 aprint_verbose_dev(self, "TCO (watchdog) timer configured.\n"); 601 aprint_verbose_dev(self, "TCO (watchdog) timer configured.\n");
602} 602}
603 603
604static int 604static int
605tcotimer_unconfigure(device_t self, int flags) 605tcotimer_unconfigure(device_t self, int flags)
606{ 606{
607 struct lpcib_softc *sc = device_private(self); 607 struct lpcib_softc *sc = device_private(self);
608 int rc; 608 int rc;
609 609
610 if ((rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) { 610 if ((rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) {
611 if (rc == ERESTART) 611 if (rc == ERESTART)
612 rc = EINTR; 612 rc = EINTR;
613 return rc; 613 return rc;
614 } 614 }
615 615
616 /* Explicitly stop the TCO timer. */ 616 /* Explicitly stop the TCO timer. */
617 tcotimer_stop(sc); 617 tcotimer_stop(sc);
618 618
619 /* XXX Set No Reboot? */ 619 /* XXX Set No Reboot? */
620 620
621 return 0; 621 return 0;
622} 622}
623 623
624 624
625/* 625/*
626 * Sysmon watchdog callbacks. 626 * Sysmon watchdog callbacks.
627 */ 627 */
628static int 628static int
629tcotimer_setmode(struct sysmon_wdog *smw) 629tcotimer_setmode(struct sysmon_wdog *smw)
630{ 630{
631 struct lpcib_softc *sc = smw->smw_cookie; 631 struct lpcib_softc *sc = smw->smw_cookie;
632 unsigned int period; 632 unsigned int period;
633 uint16_t ich6period = 0; 633 uint16_t ich6period = 0;
634 uint8_t ich5period = 0; 634 uint8_t ich5period = 0;
635 635
636 if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { 636 if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
637 /* Stop the TCO timer. */ 637 /* Stop the TCO timer. */
638 tcotimer_stop(sc); 638 tcotimer_stop(sc);
639 } else { 639 } else {
640 /*  640 /*
641 * ICH6 or newer are limited to 2s min and 613s max. 641 * ICH6 or newer are limited to 2s min and 613s max.
642 * ICH5 or older are limited to 4s min and 39s max. 642 * ICH5 or older are limited to 4s min and 39s max.
643 */ 643 */
644 period = lpcib_tcotimer_second_to_tick(smw->smw_period); 644 period = lpcib_tcotimer_second_to_tick(smw->smw_period);
645 if (sc->sc_has_rcba) { 645 if (sc->sc_has_rcba) {
646 if (period < LPCIB_TCOTIMER2_MIN_TICK || 646 if (period < LPCIB_TCOTIMER2_MIN_TICK ||
647 period > LPCIB_TCOTIMER2_MAX_TICK) 647 period > LPCIB_TCOTIMER2_MAX_TICK)
648 return EINVAL; 648 return EINVAL;
649 } else { 649 } else {
650 if (period < LPCIB_TCOTIMER_MIN_TICK || 650 if (period < LPCIB_TCOTIMER_MIN_TICK ||
651 period > LPCIB_TCOTIMER_MAX_TICK) 651 period > LPCIB_TCOTIMER_MAX_TICK)
652 return EINVAL; 652 return EINVAL;
653 } 653 }
654  654
655 /* Stop the TCO timer, */ 655 /* Stop the TCO timer, */
656 tcotimer_stop(sc); 656 tcotimer_stop(sc);
657 657
658 /* set the timeout, */ 658 /* set the timeout, */
659 if (sc->sc_has_rcba) { 659 if (sc->sc_has_rcba) {
660 /* ICH6 or newer */ 660 /* ICH6 or newer */
661 ich6period = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 661 ich6period = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
662 LPCIB_TCO_TMR2); 662 LPCIB_TCO_TMR2);
663 ich6period &= 0xfc00; 663 ich6period &= 0xfc00;
664 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 664 bus_space_write_2(sc->sc_iot, sc->sc_ioh,
665 LPCIB_TCO_TMR2, ich6period | period); 665 LPCIB_TCO_TMR2, ich6period | period);
666 } else { 666 } else {
667 /* ICH5 or older */ 667 /* ICH5 or older */
668 ich5period = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 668 ich5period = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
669 LPCIB_TCO_TMR); 669 LPCIB_TCO_TMR);
670 ich5period &= 0xc0; 670 ich5period &= 0xc0;
671 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 671 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
672 LPCIB_TCO_TMR, ich5period | period); 672 LPCIB_TCO_TMR, ich5period | period);
673 } 673 }
674 674
675 /* and start/reload the timer. */ 675 /* and start/reload the timer. */
676 tcotimer_start(sc); 676 tcotimer_start(sc);
677 tcotimer_tickle(smw); 677 tcotimer_tickle(smw);
678 } 678 }
679 679
680 return 0; 680 return 0;
681} 681}
682 682
683static int 683static int
684tcotimer_tickle(struct sysmon_wdog *smw) 684tcotimer_tickle(struct sysmon_wdog *smw)
685{ 685{
686 struct lpcib_softc *sc = smw->smw_cookie; 686 struct lpcib_softc *sc = smw->smw_cookie;
687 687
688 /* any value is allowed */ 688 /* any value is allowed */
689 if (sc->sc_has_rcba) 689 if (sc->sc_has_rcba)
690 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1); 690 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1);
691 else 691 else
692 bus_space_write_1(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1); 692 bus_space_write_1(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1);
693 693
694 return 0; 694 return 0;
695} 695}
696 696
697static void 697static void
698tcotimer_stop(struct lpcib_softc *sc) 698tcotimer_stop(struct lpcib_softc *sc)
699{ 699{
700 uint16_t ioreg; 700 uint16_t ioreg;
701 701
702 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT); 702 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT);
703 ioreg |= LPCIB_TCO1_CNT_TCO_TMR_HLT; 703 ioreg |= LPCIB_TCO1_CNT_TCO_TMR_HLT;
704 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg); 704 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg);
705} 705}
706 706
707static void 707static void
708tcotimer_start(struct lpcib_softc *sc) 708tcotimer_start(struct lpcib_softc *sc)
709{ 709{
710 uint16_t ioreg; 710 uint16_t ioreg;
711 711
712 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT); 712 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT);
713 ioreg &= ~LPCIB_TCO1_CNT_TCO_TMR_HLT; 713 ioreg &= ~LPCIB_TCO1_CNT_TCO_TMR_HLT;
714 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg); 714 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg);
715} 715}
716 716
717static void 717static void
718tcotimer_status_reset(struct lpcib_softc *sc) 718tcotimer_status_reset(struct lpcib_softc *sc)
719{ 719{
720 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_STS, 720 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_STS,
721 LPCIB_TCO1_STS_TIMEOUT); 721 LPCIB_TCO1_STS_TIMEOUT);
722 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS, 722 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS,
723 LPCIB_TCO2_STS_BOOT_STS); 723 LPCIB_TCO2_STS_BOOT_STS);
724 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS, 724 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS,
725 LPCIB_TCO2_STS_SECONDS_TO_STS); 725 LPCIB_TCO2_STS_SECONDS_TO_STS);
726} 726}
727 727
728/* 728/*
729 * Clear the No Reboot (NR) bit, this enables reboots when the timer 729 * Clear the No Reboot (NR) bit, this enables reboots when the timer
730 * reaches the timeout for the second time. 730 * reaches the timeout for the second time.
731 */ 731 */
732static int 732static int
733tcotimer_disable_noreboot(device_t self) 733tcotimer_disable_noreboot(device_t self)
734{ 734{
735 struct lpcib_softc *sc = device_private(self); 735 struct lpcib_softc *sc = device_private(self);
736 736
737 if (sc->sc_has_rcba) { 737 if (sc->sc_has_rcba) {
738 uint32_t status; 738 uint32_t status;
739 739
740 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 740 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
741 LPCIB_GCS_OFFSET); 741 LPCIB_GCS_OFFSET);
742 status &= ~LPCIB_GCS_NO_REBOOT; 742 status &= ~LPCIB_GCS_NO_REBOOT;
743 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, 743 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah,
744 LPCIB_GCS_OFFSET, status); 744 LPCIB_GCS_OFFSET, status);
745 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 745 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
746 LPCIB_GCS_OFFSET); 746 LPCIB_GCS_OFFSET);
747 if (status & LPCIB_GCS_NO_REBOOT) 747 if (status & LPCIB_GCS_NO_REBOOT)
748 goto error; 748 goto error;
749 } else { 749 } else {
750 pcireg_t pcireg; 750 pcireg_t pcireg;
751 751
752 pcireg = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,  752 pcireg = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
753 LPCIB_PCI_GEN_STA); 753 LPCIB_PCI_GEN_STA);
754 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) { 754 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) {
755 /* TCO timeout reset is disabled; try to enable it */ 755 /* TCO timeout reset is disabled; try to enable it */
756 pcireg &= ~LPCIB_PCI_GEN_STA_NO_REBOOT; 756 pcireg &= ~LPCIB_PCI_GEN_STA_NO_REBOOT;
757 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 757 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
758 LPCIB_PCI_GEN_STA, pcireg); 758 LPCIB_PCI_GEN_STA, pcireg);
759 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) 759 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT)
760 goto error; 760 goto error;
761 } 761 }
762 } 762 }
763 763
764 return 0; 764 return 0;
765error: 765error:
766 aprint_error_dev(self, "TCO timer reboot disabled by hardware; " 766 aprint_error_dev(self, "TCO timer reboot disabled by hardware; "
767 "hope SMBIOS properly handles it.\n"); 767 "hope SMBIOS properly handles it.\n");
768 return EINVAL; 768 return EINVAL;
769} 769}
770 770
771 771
772/* 772/*
773 * Intel ICH SpeedStep support. 773 * Intel ICH SpeedStep support.
774 */ 774 */
775#define SS_READ(sc, reg) \ 775#define SS_READ(sc, reg) \
776 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg)) 776 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg))
777#define SS_WRITE(sc, reg, val) \ 777#define SS_WRITE(sc, reg, val) \
778 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 778 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
779 779
780/* 780/*
781 * Linux driver says that SpeedStep on older chipsets cause 781 * Linux driver says that SpeedStep on older chipsets cause
782 * lockups on Dell Inspiron 8000 and 8100. 782 * lockups on Dell Inspiron 8000 and 8100.
783 * It should also not be enabled on systems with the 82855GM 783 * It should also not be enabled on systems with the 82855GM
784 * Hub, which typically have an EST-enabled CPU. 784 * Hub, which typically have an EST-enabled CPU.
785 */ 785 */
786static int 786static int
787speedstep_bad_hb_check(const struct pci_attach_args *pa) 787speedstep_bad_hb_check(const struct pci_attach_args *pa)
788{ 788{
789 789
790 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB && 790 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB &&
791 PCI_REVISION(pa->pa_class) < 5) 791 PCI_REVISION(pa->pa_class) < 5)
792 return 1; 792 return 1;
793 793
794 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82855GM_MCH) 794 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82855GM_MCH)
795 return 1; 795 return 1;
796 796
797 return 0; 797 return 0;
798} 798}
799 799
800static void 800static void
801speedstep_configure(device_t self) 801speedstep_configure(device_t self)
802{ 802{
803 struct lpcib_softc *sc = device_private(self); 803 struct lpcib_softc *sc = device_private(self);
804 const struct sysctlnode *node, *ssnode; 804 const struct sysctlnode *node, *ssnode;
805 int rv; 805 int rv;
806 806
807 /* Supported on ICH2-M, ICH3-M and ICH4-M. */ 807 /* Supported on ICH2-M, ICH3-M and ICH4-M. */
808 if (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801DB_ISA || 808 if (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC ||
809 PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC || 809 PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC ||
810 (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC && 810 (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC &&
811 pci_find_device(&sc->sc_pa, speedstep_bad_hb_check) == 0)) { 811 pci_find_device(&sc->sc_pa, speedstep_bad_hb_check) == 0)) {
812 pcireg_t pmcon; 812 pcireg_t pmcon;
813 813
814 /* Enable SpeedStep if it isn't already enabled. */ 814 /* Enable SpeedStep if it isn't already enabled. */
815 pmcon = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 815 pmcon = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
816 LPCIB_PCI_GEN_PMCON_1); 816 LPCIB_PCI_GEN_PMCON_1);
817 if ((pmcon & LPCIB_PCI_GEN_PMCON_1_SS_EN) == 0) 817 if ((pmcon & LPCIB_PCI_GEN_PMCON_1_SS_EN) == 0)
818 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 818 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
819 LPCIB_PCI_GEN_PMCON_1, 819 LPCIB_PCI_GEN_PMCON_1,
820 pmcon | LPCIB_PCI_GEN_PMCON_1_SS_EN); 820 pmcon | LPCIB_PCI_GEN_PMCON_1_SS_EN);
821 821
822 /* Put in machdep.speedstep_state (0 for low, 1 for high). */ 822 /* Put in machdep.speedstep_state (0 for low, 1 for high). */
823 if ((rv = sysctl_createv(&sc->sc_log, 0, NULL, &node, 823 if ((rv = sysctl_createv(&sc->sc_log, 0, NULL, &node,
824 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 824 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
825 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0) 825 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
826 goto err; 826 goto err;
827 827
828 /* CTLFLAG_ANYWRITE? kernel option like EST? */ 828 /* CTLFLAG_ANYWRITE? kernel option like EST? */
829 if ((rv = sysctl_createv(&sc->sc_log, 0, &node, &ssnode, 829 if ((rv = sysctl_createv(&sc->sc_log, 0, &node, &ssnode,
830 CTLFLAG_READWRITE, CTLTYPE_INT, "speedstep_state", NULL, 830 CTLFLAG_READWRITE, CTLTYPE_INT, "speedstep_state", NULL,
831 speedstep_sysctl_helper, 0, NULL, 0, CTL_CREATE, 831 speedstep_sysctl_helper, 0, NULL, 0, CTL_CREATE,
832 CTL_EOL)) != 0) 832 CTL_EOL)) != 0)
833 goto err; 833 goto err;
834 834
835 /* XXX save the sc for IO tag/handle */ 835 /* XXX save the sc for IO tag/handle */
836 speedstep_cookie = sc; 836 speedstep_cookie = sc;
837 aprint_verbose_dev(self, "SpeedStep enabled\n"); 837 aprint_verbose_dev(self, "SpeedStep enabled\n");
838 } 838 }
839 839
840 return; 840 return;
841 841
842err: 842err:
843 aprint_normal("%s: sysctl_createv failed (rv = %d)\n", __func__, rv); 843 aprint_normal("%s: sysctl_createv failed (rv = %d)\n", __func__, rv);
844} 844}
845 845
846static void 846static void
847speedstep_unconfigure(device_t self) 847speedstep_unconfigure(device_t self)
848{ 848{
849 struct lpcib_softc *sc = device_private(self); 849 struct lpcib_softc *sc = device_private(self);
850 850
851 sysctl_teardown(&sc->sc_log); 851 sysctl_teardown(&sc->sc_log);
852 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 852 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
853 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 853 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig);
854 854
855 speedstep_cookie = NULL; 855 speedstep_cookie = NULL;
856} 856}
857 857
858/* 858/*
859 * get/set the SpeedStep state: 0 == low power, 1 == high power. 859 * get/set the SpeedStep state: 0 == low power, 1 == high power.
860 */ 860 */
861static int 861static int
862speedstep_sysctl_helper(SYSCTLFN_ARGS) 862speedstep_sysctl_helper(SYSCTLFN_ARGS)
863{ 863{
864 struct sysctlnode node; 864 struct sysctlnode node;
865 struct lpcib_softc *sc = speedstep_cookie; 865 struct lpcib_softc *sc = speedstep_cookie;
866 uint8_t state, state2; 866 uint8_t state, state2;
867 int ostate, nstate, s, error = 0; 867 int ostate, nstate, s, error = 0;
868 868
869 /* 869 /*
870 * We do the dance with spl's to avoid being at high ipl during 870 * We do the dance with spl's to avoid being at high ipl during
871 * sysctl_lookup() which can both copyin and copyout. 871 * sysctl_lookup() which can both copyin and copyout.
872 */ 872 */
873 s = splserial(); 873 s = splserial();
874 state = SS_READ(sc, LPCIB_PM_SS_CNTL); 874 state = SS_READ(sc, LPCIB_PM_SS_CNTL);
875 splx(s); 875 splx(s);
876 if ((state & LPCIB_PM_SS_STATE_LOW) == 0) 876 if ((state & LPCIB_PM_SS_STATE_LOW) == 0)
877 ostate = 1; 877 ostate = 1;
878 else 878 else
879 ostate = 0; 879 ostate = 0;
880 nstate = ostate; 880 nstate = ostate;
881 881
882 node = *rnode; 882 node = *rnode;
883 node.sysctl_data = &nstate; 883 node.sysctl_data = &nstate;
884 884
885 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 885 error = sysctl_lookup(SYSCTLFN_CALL(&node));
886 if (error || newp == NULL) 886 if (error || newp == NULL)
887 goto out; 887 goto out;
888 888
889 /* Only two states are available */ 889 /* Only two states are available */
890 if (nstate != 0 && nstate != 1) { 890 if (nstate != 0 && nstate != 1) {
891 error = EINVAL; 891 error = EINVAL;
892 goto out; 892 goto out;
893 } 893 }
894 894
895 s = splserial(); 895 s = splserial();
896 state2 = SS_READ(sc, LPCIB_PM_SS_CNTL); 896 state2 = SS_READ(sc, LPCIB_PM_SS_CNTL);
897 if ((state2 & LPCIB_PM_SS_STATE_LOW) == 0) 897 if ((state2 & LPCIB_PM_SS_STATE_LOW) == 0)
898 ostate = 1; 898 ostate = 1;
899 else 899 else
900 ostate = 0; 900 ostate = 0;
901 901
902 if (ostate != nstate) { 902 if (ostate != nstate) {
903 uint8_t cntl; 903 uint8_t cntl;
904 904
905 if (nstate == 0) 905 if (nstate == 0)
906 state2 |= LPCIB_PM_SS_STATE_LOW; 906 state2 |= LPCIB_PM_SS_STATE_LOW;
907 else 907 else
908 state2 &= ~LPCIB_PM_SS_STATE_LOW; 908 state2 &= ~LPCIB_PM_SS_STATE_LOW;
909 909
910 /* 910 /*
911 * Must disable bus master arbitration during the change. 911 * Must disable bus master arbitration during the change.
912 */ 912 */
913 cntl = SS_READ(sc, LPCIB_PM_CTRL); 913 cntl = SS_READ(sc, LPCIB_PM_CTRL);
914 SS_WRITE(sc, LPCIB_PM_CTRL, cntl | LPCIB_PM_SS_CNTL_ARB_DIS); 914 SS_WRITE(sc, LPCIB_PM_CTRL, cntl | LPCIB_PM_SS_CNTL_ARB_DIS);
915 SS_WRITE(sc, LPCIB_PM_SS_CNTL, state2); 915 SS_WRITE(sc, LPCIB_PM_SS_CNTL, state2);
916 SS_WRITE(sc, LPCIB_PM_CTRL, cntl); 916 SS_WRITE(sc, LPCIB_PM_CTRL, cntl);
917 } 917 }
918 splx(s); 918 splx(s);
919out: 919out:
920 return error; 920 return error;
921} 921}
922 922
923#if NHPET > 0 923#if NHPET > 0
924struct lpcib_hpet_attach_arg { 924struct lpcib_hpet_attach_arg {
925 bus_space_tag_t hpet_mem_t; 925 bus_space_tag_t hpet_mem_t;
926 uint32_t hpet_reg; 926 uint32_t hpet_reg;
927}; 927};
928 928
929static int 929static int
930lpcib_hpet_match(device_t parent, cfdata_t match, void *aux) 930lpcib_hpet_match(device_t parent, cfdata_t match, void *aux)
931{ 931{
932 struct lpcib_hpet_attach_arg *arg = aux; 932 struct lpcib_hpet_attach_arg *arg = aux;
933 bus_space_tag_t tag; 933 bus_space_tag_t tag;
934 bus_space_handle_t handle; 934 bus_space_handle_t handle;
935 935
936 tag = arg->hpet_mem_t; 936 tag = arg->hpet_mem_t;
937 937
938 if (bus_space_map(tag, arg->hpet_reg, HPET_WINDOW_SIZE, 0, &handle)) { 938 if (bus_space_map(tag, arg->hpet_reg, HPET_WINDOW_SIZE, 0, &handle)) {
939 aprint_verbose_dev(parent, "HPET window not mapped, skipping\n"); 939 aprint_verbose_dev(parent, "HPET window not mapped, skipping\n");
940 return 0; 940 return 0;
941 } 941 }
942 bus_space_unmap(tag, handle, HPET_WINDOW_SIZE); 942 bus_space_unmap(tag, handle, HPET_WINDOW_SIZE);
943 943
944 return 1; 944 return 1;
945} 945}
946 946
947static int 947static int
948lpcib_hpet_detach(device_t self, int flags) 948lpcib_hpet_detach(device_t self, int flags)
949{ 949{
950 struct hpet_softc *sc = device_private(self); 950 struct hpet_softc *sc = device_private(self);
951 int rc; 951 int rc;
952 952
953 if ((rc = hpet_detach(self, flags)) != 0) 953 if ((rc = hpet_detach(self, flags)) != 0)
954 return rc; 954 return rc;
955 955
956 bus_space_unmap(sc->sc_memt, sc->sc_memh, HPET_WINDOW_SIZE); 956 bus_space_unmap(sc->sc_memt, sc->sc_memh, HPET_WINDOW_SIZE);
957 957
958 return 0; 958 return 0;
959} 959}
960 960
961static void 961static void
962lpcib_hpet_attach(device_t parent, device_t self, void *aux) 962lpcib_hpet_attach(device_t parent, device_t self, void *aux)
963{ 963{
964 struct hpet_softc *sc = device_private(self); 964 struct hpet_softc *sc = device_private(self);
965 struct lpcib_hpet_attach_arg *arg = aux; 965 struct lpcib_hpet_attach_arg *arg = aux;
966 966
967 aprint_naive("\n"); 967 aprint_naive("\n");
968 aprint_normal("\n"); 968 aprint_normal("\n");
969 969
970 sc->sc_memt = arg->hpet_mem_t; 970 sc->sc_memt = arg->hpet_mem_t;
971 971
972 if (bus_space_map(sc->sc_memt, arg->hpet_reg, HPET_WINDOW_SIZE, 0, 972 if (bus_space_map(sc->sc_memt, arg->hpet_reg, HPET_WINDOW_SIZE, 0,
973 &sc->sc_memh)) { 973 &sc->sc_memh)) {
974 aprint_error_dev(self, 974 aprint_error_dev(self,
975 "HPET memory window could not be mapped"); 975 "HPET memory window could not be mapped");
976 return; 976 return;
977 } 977 }
978 978
979 hpet_attach_subr(self); 979 hpet_attach_subr(self);
980} 980}
981 981
982CFATTACH_DECL_NEW(ichlpcib_hpet, sizeof(struct hpet_softc), lpcib_hpet_match, 982CFATTACH_DECL_NEW(ichlpcib_hpet, sizeof(struct hpet_softc), lpcib_hpet_match,
983 lpcib_hpet_attach, lpcib_hpet_detach, NULL); 983 lpcib_hpet_attach, lpcib_hpet_detach, NULL);
984 984
985static void 985static void
986lpcib_hpet_configure(device_t self) 986lpcib_hpet_configure(device_t self)
987{ 987{
988 struct lpcib_softc *sc = device_private(self); 988 struct lpcib_softc *sc = device_private(self);
989 struct lpcib_hpet_attach_arg arg; 989 struct lpcib_hpet_attach_arg arg;
990 uint32_t hpet_reg, val; 990 uint32_t hpet_reg, val;
991 991
992 if (sc->sc_has_ich5_hpet) { 992 if (sc->sc_has_ich5_hpet) {
993 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 993 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
994 LPCIB_PCI_GEN_CNTL); 994 LPCIB_PCI_GEN_CNTL);
995 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 995 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) {
996 case LPCIB_ICH5_HPTC_0000: 996 case LPCIB_ICH5_HPTC_0000:
997 hpet_reg = LPCIB_ICH5_HPTC_0000_BASE; 997 hpet_reg = LPCIB_ICH5_HPTC_0000_BASE;
998 break; 998 break;
999 case LPCIB_ICH5_HPTC_1000: 999 case LPCIB_ICH5_HPTC_1000:
1000 hpet_reg = LPCIB_ICH5_HPTC_1000_BASE; 1000 hpet_reg = LPCIB_ICH5_HPTC_1000_BASE;
1001 break; 1001 break;
1002 case LPCIB_ICH5_HPTC_2000: 1002 case LPCIB_ICH5_HPTC_2000:
1003 hpet_reg = LPCIB_ICH5_HPTC_2000_BASE; 1003 hpet_reg = LPCIB_ICH5_HPTC_2000_BASE;
1004 break; 1004 break;
1005 case LPCIB_ICH5_HPTC_3000: 1005 case LPCIB_ICH5_HPTC_3000:
1006 hpet_reg = LPCIB_ICH5_HPTC_3000_BASE; 1006 hpet_reg = LPCIB_ICH5_HPTC_3000_BASE;
1007 break; 1007 break;
1008 default: 1008 default:
1009 return; 1009 return;
1010 } 1010 }
1011 val |= sc->sc_hpet_reg | LPCIB_ICH5_HPTC_EN; 1011 val |= sc->sc_hpet_reg | LPCIB_ICH5_HPTC_EN;
1012 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1012 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1013 LPCIB_PCI_GEN_CNTL, val); 1013 LPCIB_PCI_GEN_CNTL, val);
1014 } else if (sc->sc_has_rcba) { 1014 } else if (sc->sc_has_rcba) {
1015 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 1015 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah,
1016 LPCIB_RCBA_HPTC); 1016 LPCIB_RCBA_HPTC);
1017 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 1017 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) {
1018 case LPCIB_RCBA_HPTC_0000: 1018 case LPCIB_RCBA_HPTC_0000:
1019 hpet_reg = LPCIB_RCBA_HPTC_0000_BASE; 1019 hpet_reg = LPCIB_RCBA_HPTC_0000_BASE;
1020 break; 1020 break;
1021 case LPCIB_RCBA_HPTC_1000: 1021 case LPCIB_RCBA_HPTC_1000:
1022 hpet_reg = LPCIB_RCBA_HPTC_1000_BASE; 1022 hpet_reg = LPCIB_RCBA_HPTC_1000_BASE;
1023 break; 1023 break;
1024 case LPCIB_RCBA_HPTC_2000: 1024 case LPCIB_RCBA_HPTC_2000:
1025 hpet_reg = LPCIB_RCBA_HPTC_2000_BASE; 1025 hpet_reg = LPCIB_RCBA_HPTC_2000_BASE;
1026 break; 1026 break;
1027 case LPCIB_RCBA_HPTC_3000: 1027 case LPCIB_RCBA_HPTC_3000:
1028 hpet_reg = LPCIB_RCBA_HPTC_3000_BASE; 1028 hpet_reg = LPCIB_RCBA_HPTC_3000_BASE;
1029 break; 1029 break;
1030 default: 1030 default:
1031 return; 1031 return;
1032 } 1032 }
1033 val |= LPCIB_RCBA_HPTC_EN; 1033 val |= LPCIB_RCBA_HPTC_EN;
1034 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 1034 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC,
1035 val); 1035 val);
1036 } else { 1036 } else {
1037 /* No HPET here */ 1037 /* No HPET here */
1038 return; 1038 return;
1039 } 1039 }
1040 1040
1041 arg.hpet_mem_t = sc->sc_pa.pa_memt; 1041 arg.hpet_mem_t = sc->sc_pa.pa_memt;
1042 arg.hpet_reg = hpet_reg; 1042 arg.hpet_reg = hpet_reg;
1043 1043
1044 sc->sc_hpetbus = config_found_ia(self, "hpetichbus", &arg, NULL); 1044 sc->sc_hpetbus = config_found_ia(self, "hpetichbus", &arg, NULL);
1045} 1045}
1046 1046
1047static int 1047static int
1048lpcib_hpet_unconfigure(device_t self, int flags) 1048lpcib_hpet_unconfigure(device_t self, int flags)
1049{ 1049{
1050 struct lpcib_softc *sc = device_private(self); 1050 struct lpcib_softc *sc = device_private(self);
1051 int rc; 1051 int rc;
1052 1052
1053 if (sc->sc_hpetbus != NULL && 1053 if (sc->sc_hpetbus != NULL &&
1054 (rc = config_detach(sc->sc_hpetbus, flags)) != 0) 1054 (rc = config_detach(sc->sc_hpetbus, flags)) != 0)
1055 return rc; 1055 return rc;
1056 1056
1057 return 0; 1057 return 0;
1058} 1058}
1059#endif 1059#endif
1060 1060
1061#if NGPIO > 0 1061#if NGPIO > 0
1062static void 1062static void
1063lpcib_gpio_configure(device_t self) 1063lpcib_gpio_configure(device_t self)
1064{ 1064{
1065 struct lpcib_softc *sc = device_private(self); 1065 struct lpcib_softc *sc = device_private(self);
1066 struct gpiobus_attach_args gba; 1066 struct gpiobus_attach_args gba;
1067 pcireg_t gpio_cntl; 1067 pcireg_t gpio_cntl;
1068 uint32_t use, io, bit; 1068 uint32_t use, io, bit;
1069 int pin, shift, base_reg, cntl_reg, reg; 1069 int pin, shift, base_reg, cntl_reg, reg;
1070 1070
1071 /* this implies ICH >= 6, and thus different mapreg */ 1071 /* this implies ICH >= 6, and thus different mapreg */
1072 if (sc->sc_has_rcba) { 1072 if (sc->sc_has_rcba) {
1073 base_reg = LPCIB_PCI_GPIO_BASE_ICH6; 1073 base_reg = LPCIB_PCI_GPIO_BASE_ICH6;
1074 cntl_reg = LPCIB_PCI_GPIO_CNTL_ICH6; 1074 cntl_reg = LPCIB_PCI_GPIO_CNTL_ICH6;
1075 } else { 1075 } else {
1076 base_reg = LPCIB_PCI_GPIO_BASE; 1076 base_reg = LPCIB_PCI_GPIO_BASE;
1077 cntl_reg = LPCIB_PCI_GPIO_CNTL; 1077 cntl_reg = LPCIB_PCI_GPIO_CNTL;
1078 } 1078 }
1079 1079
1080 gpio_cntl = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1080 gpio_cntl = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1081 cntl_reg); 1081 cntl_reg);
1082 1082
1083 /* Is GPIO enabled? */ 1083 /* Is GPIO enabled? */
1084 if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0) 1084 if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0)
1085 return; 1085 return;
1086  1086
1087 if (pci_mapreg_map(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0, 1087 if (pci_mapreg_map(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0,
1088 &sc->sc_gpio_iot, &sc->sc_gpio_ioh, 1088 &sc->sc_gpio_iot, &sc->sc_gpio_ioh,
1089 NULL, &sc->sc_gpio_ios)) { 1089 NULL, &sc->sc_gpio_ios)) {
1090 aprint_error_dev(self, "can't map general purpose i/o space\n"); 1090 aprint_error_dev(self, "can't map general purpose i/o space\n");
1091 return; 1091 return;
1092 } 1092 }
1093 1093
1094 mutex_init(&sc->sc_gpio_mtx, MUTEX_DEFAULT, IPL_NONE); 1094 mutex_init(&sc->sc_gpio_mtx, MUTEX_DEFAULT, IPL_NONE);
1095 1095
1096 for (pin = 0; pin < LPCIB_GPIO_NPINS; pin++) { 1096 for (pin = 0; pin < LPCIB_GPIO_NPINS; pin++) {
1097 sc->sc_gpio_pins[pin].pin_num = pin; 1097 sc->sc_gpio_pins[pin].pin_num = pin;
1098 1098
1099 /* Read initial state */ 1099 /* Read initial state */
1100 reg = (pin < 32) ? LPCIB_GPIO_GPIO_USE_SEL : LPCIB_GPIO_GPIO_USE_SEL2; 1100 reg = (pin < 32) ? LPCIB_GPIO_GPIO_USE_SEL : LPCIB_GPIO_GPIO_USE_SEL2;
1101 use = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1101 use = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1102 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL; 1102 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL;
1103 io = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, 4); 1103 io = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, 4);
1104 shift = pin % 32; 1104 shift = pin % 32;
1105 bit = __BIT(shift); 1105 bit = __BIT(shift);
1106 1106
1107 if ((use & bit) != 0) { 1107 if ((use & bit) != 0) {
1108 sc->sc_gpio_pins[pin].pin_caps = 1108 sc->sc_gpio_pins[pin].pin_caps =
1109 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 1109 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
1110 if (pin < 32) 1110 if (pin < 32)
1111 sc->sc_gpio_pins[pin].pin_caps |= 1111 sc->sc_gpio_pins[pin].pin_caps |=
1112 GPIO_PIN_PULSATE; 1112 GPIO_PIN_PULSATE;
1113 if ((io & bit) != 0) 1113 if ((io & bit) != 0)
1114 sc->sc_gpio_pins[pin].pin_flags = 1114 sc->sc_gpio_pins[pin].pin_flags =
1115 GPIO_PIN_INPUT; 1115 GPIO_PIN_INPUT;
1116 else 1116 else
1117 sc->sc_gpio_pins[pin].pin_flags = 1117 sc->sc_gpio_pins[pin].pin_flags =
1118 GPIO_PIN_OUTPUT; 1118 GPIO_PIN_OUTPUT;
1119 } else 1119 } else
1120 sc->sc_gpio_pins[pin].pin_caps = 0; 1120 sc->sc_gpio_pins[pin].pin_caps = 0;
1121 1121
1122 if (lpcib_gpio_pin_read(sc, pin) == 0) 1122 if (lpcib_gpio_pin_read(sc, pin) == 0)
1123 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW; 1123 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW;
1124 else 1124 else
1125 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH; 1125 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH;
1126 1126
1127 } 1127 }
1128 1128
1129 /* Create controller tag */ 1129 /* Create controller tag */
1130 sc->sc_gpio_gc.gp_cookie = sc; 1130 sc->sc_gpio_gc.gp_cookie = sc;
1131 sc->sc_gpio_gc.gp_pin_read = lpcib_gpio_pin_read; 1131 sc->sc_gpio_gc.gp_pin_read = lpcib_gpio_pin_read;
1132 sc->sc_gpio_gc.gp_pin_write = lpcib_gpio_pin_write; 1132 sc->sc_gpio_gc.gp_pin_write = lpcib_gpio_pin_write;
1133 sc->sc_gpio_gc.gp_pin_ctl = lpcib_gpio_pin_ctl; 1133 sc->sc_gpio_gc.gp_pin_ctl = lpcib_gpio_pin_ctl;
1134 1134
1135 memset(&gba, 0, sizeof(gba)); 1135 memset(&gba, 0, sizeof(gba));
1136 1136
1137 gba.gba_gc = &sc->sc_gpio_gc; 1137 gba.gba_gc = &sc->sc_gpio_gc;
1138 gba.gba_pins = sc->sc_gpio_pins; 1138 gba.gba_pins = sc->sc_gpio_pins;
1139 gba.gba_npins = LPCIB_GPIO_NPINS; 1139 gba.gba_npins = LPCIB_GPIO_NPINS;
1140 1140
1141 sc->sc_gpiobus = config_found_ia(self, "gpiobus", &gba, gpiobus_print); 1141 sc->sc_gpiobus = config_found_ia(self, "gpiobus", &gba, gpiobus_print);
1142} 1142}
1143 1143
1144static int 1144static int
1145lpcib_gpio_unconfigure(device_t self, int flags) 1145lpcib_gpio_unconfigure(device_t self, int flags)
1146{ 1146{
1147 struct lpcib_softc *sc = device_private(self); 1147 struct lpcib_softc *sc = device_private(self);
1148 int rc; 1148 int rc;
1149 1149
1150 if (sc->sc_gpiobus != NULL && 1150 if (sc->sc_gpiobus != NULL &&
1151 (rc = config_detach(sc->sc_gpiobus, flags)) != 0) 1151 (rc = config_detach(sc->sc_gpiobus, flags)) != 0)
1152 return rc; 1152 return rc;
1153 1153
1154 mutex_destroy(&sc->sc_gpio_mtx); 1154 mutex_destroy(&sc->sc_gpio_mtx);
1155 1155
1156 bus_space_unmap(sc->sc_gpio_iot, sc->sc_gpio_ioh, sc->sc_gpio_ios); 1156 bus_space_unmap(sc->sc_gpio_iot, sc->sc_gpio_ioh, sc->sc_gpio_ios);
1157 1157
1158 return 0; 1158 return 0;
1159} 1159}
1160 1160
1161static int 1161static int
1162lpcib_gpio_pin_read(void *arg, int pin) 1162lpcib_gpio_pin_read(void *arg, int pin)
1163{ 1163{
1164 struct lpcib_softc *sc = arg; 1164 struct lpcib_softc *sc = arg;
1165 uint32_t data; 1165 uint32_t data;
1166 int reg, shift; 1166 int reg, shift;
1167  1167
1168 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 1168 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2;
1169 shift = pin % 32; 1169 shift = pin % 32;
1170 1170
1171 mutex_enter(&sc->sc_gpio_mtx); 1171 mutex_enter(&sc->sc_gpio_mtx);
1172 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1172 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1173 mutex_exit(&sc->sc_gpio_mtx); 1173 mutex_exit(&sc->sc_gpio_mtx);
1174  1174
1175 return (__SHIFTOUT(data, __BIT(shift)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW); 1175 return (__SHIFTOUT(data, __BIT(shift)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
1176} 1176}
1177 1177
1178static void 1178static void
1179lpcib_gpio_pin_write(void *arg, int pin, int value) 1179lpcib_gpio_pin_write(void *arg, int pin, int value)
1180{ 1180{
1181 struct lpcib_softc *sc = arg; 1181 struct lpcib_softc *sc = arg;
1182 uint32_t data; 1182 uint32_t data;
1183 int reg, shift; 1183 int reg, shift;
1184 1184
1185 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 1185 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2;
1186 shift = pin % 32; 1186 shift = pin % 32;
1187 1187
1188 mutex_enter(&sc->sc_gpio_mtx); 1188 mutex_enter(&sc->sc_gpio_mtx);
1189 1189
1190 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1190 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1191 1191
1192 if(value) 1192 if(value)
1193 data |= __BIT(shift); 1193 data |= __BIT(shift);
1194 else 1194 else
1195 data &= ~__BIT(shift); 1195 data &= ~__BIT(shift);
1196 1196
1197 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1197 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1198 1198
1199 mutex_exit(&sc->sc_gpio_mtx); 1199 mutex_exit(&sc->sc_gpio_mtx);
1200} 1200}
1201 1201
1202static void 1202static void
1203lpcib_gpio_pin_ctl(void *arg, int pin, int flags) 1203lpcib_gpio_pin_ctl(void *arg, int pin, int flags)
1204{ 1204{
1205 struct lpcib_softc *sc = arg; 1205 struct lpcib_softc *sc = arg;
1206 uint32_t data; 1206 uint32_t data;
1207 int reg, shift; 1207 int reg, shift;
1208 1208
1209 shift = pin % 32; 1209 shift = pin % 32;
1210 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL2; 1210 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL2;
1211  1211
1212 mutex_enter(&sc->sc_gpio_mtx); 1212 mutex_enter(&sc->sc_gpio_mtx);
1213  1213
1214 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1214 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1215  1215
1216 if (flags & GPIO_PIN_OUTPUT) 1216 if (flags & GPIO_PIN_OUTPUT)
1217 data &= ~__BIT(shift); 1217 data &= ~__BIT(shift);
1218 1218
1219 if (flags & GPIO_PIN_INPUT) 1219 if (flags & GPIO_PIN_INPUT)
1220 data |= __BIT(shift); 1220 data |= __BIT(shift);
1221 1221
1222 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1222 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1223 1223
1224 1224
1225 if (pin < 32) { 1225 if (pin < 32) {
1226 reg = LPCIB_GPIO_GPO_BLINK; 1226 reg = LPCIB_GPIO_GPO_BLINK;
1227 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1227 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
1228 1228
1229 if (flags & GPIO_PIN_PULSATE) 1229 if (flags & GPIO_PIN_PULSATE)
1230 data |= __BIT(shift); 1230 data |= __BIT(shift);
1231 else 1231 else
1232 data &= ~__BIT(shift); 1232 data &= ~__BIT(shift);
1233 1233
1234 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1234 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
1235 } 1235 }
1236 1236
1237 mutex_exit(&sc->sc_gpio_mtx); 1237 mutex_exit(&sc->sc_gpio_mtx);
1238} 1238}
1239#endif 1239#endif
1240 1240
1241#if NFWHRNG > 0 1241#if NFWHRNG > 0
1242static void 1242static void
1243lpcib_fwh_configure(device_t self) 1243lpcib_fwh_configure(device_t self)
1244{ 1244{
1245 struct lpcib_softc *sc; 1245 struct lpcib_softc *sc;
1246 pcireg_t pr; 1246 pcireg_t pr;
1247 1247
1248 sc = device_private(self); 1248 sc = device_private(self);
1249 1249
1250 if (sc->sc_has_rcba) { 1250 if (sc->sc_has_rcba) {
1251 /* 1251 /*
1252 * Very unlikely to find a 82802 on a ICH6 or newer. 1252 * Very unlikely to find a 82802 on a ICH6 or newer.
1253 * Also the write enable register moved at that point. 1253 * Also the write enable register moved at that point.
1254 */ 1254 */
1255 return; 1255 return;
1256 } else { 1256 } else {
1257 /* Enable FWH write to identify FWH. */ 1257 /* Enable FWH write to identify FWH. */
1258 pr = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1258 pr = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1259 LPCIB_PCI_BIOS_CNTL); 1259 LPCIB_PCI_BIOS_CNTL);
1260 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1260 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1261 LPCIB_PCI_BIOS_CNTL, pr|LPCIB_PCI_BIOS_CNTL_BWE); 1261 LPCIB_PCI_BIOS_CNTL, pr|LPCIB_PCI_BIOS_CNTL_BWE);
1262 } 1262 }
1263 1263
1264 sc->sc_fwhbus = config_found_ia(self, "fwhichbus", NULL, NULL); 1264 sc->sc_fwhbus = config_found_ia(self, "fwhichbus", NULL, NULL);
1265 1265
1266 /* restore previous write enable setting */ 1266 /* restore previous write enable setting */
1267 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1267 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag,
1268 LPCIB_PCI_BIOS_CNTL, pr); 1268 LPCIB_PCI_BIOS_CNTL, pr);
1269} 1269}
1270 1270
1271static int 1271static int
1272lpcib_fwh_unconfigure(device_t self, int flags) 1272lpcib_fwh_unconfigure(device_t self, int flags)
1273{ 1273{
1274 struct lpcib_softc *sc = device_private(self); 1274 struct lpcib_softc *sc = device_private(self);
1275 int rc; 1275 int rc;
1276 1276
1277 if (sc->sc_fwhbus != NULL && 1277 if (sc->sc_fwhbus != NULL &&
1278 (rc = config_detach(sc->sc_fwhbus, flags)) != 0) 1278 (rc = config_detach(sc->sc_fwhbus, flags)) != 0)
1279 return rc; 1279 return rc;
1280 1280
1281 return 0; 1281 return 0;
1282} 1282}
1283#endif 1283#endif