@@ -167,6 +167,97 @@ void __init isa_bridge_find_early(struct pci_controller *hose)
167
167
pr_debug ("ISA bridge (early) is %s\n" , np -> full_name );
168
168
}
169
169
170
+ /**
171
+ * isa_bridge_find_early - Find and map the ISA IO space early before
172
+ * main PCI discovery. This is optionally called by
173
+ * the arch code when adding PCI PHBs to get early
174
+ * access to ISA IO ports
175
+ */
176
+ void __init isa_bridge_init_non_pci (struct device_node * np )
177
+ {
178
+ const __be32 * ranges , * pbasep = NULL ;
179
+ int rlen , i , rs ;
180
+ u32 na , ns , pna ;
181
+ u64 cbase , pbase , size = 0 ;
182
+
183
+ /* If we already have an ISA bridge, bail off */
184
+ if (isa_bridge_devnode != NULL )
185
+ return ;
186
+
187
+ pna = of_n_addr_cells (np );
188
+ if (of_property_read_u32 (np , "#address-cells" , & na ) ||
189
+ of_property_read_u32 (np , "#size-cells" , & ns )) {
190
+ pr_warn ("ISA: Non-PCI bridge %s is missing address format\n" ,
191
+ np -> full_name );
192
+ return ;
193
+ }
194
+
195
+ /* Check it's a supported address format */
196
+ if (na != 2 || ns != 1 ) {
197
+ pr_warn ("ISA: Non-PCI bridge %s has unsupported address format\n" ,
198
+ np -> full_name );
199
+ return ;
200
+ }
201
+ rs = na + ns + pna ;
202
+
203
+ /* Grab the ranges property */
204
+ ranges = of_get_property (np , "ranges" , & rlen );
205
+ if (ranges == NULL || rlen < rs ) {
206
+ pr_warn ("ISA: Non-PCI bridge %s has absent or invalid ranges\n" ,
207
+ np -> full_name );
208
+ return ;
209
+ }
210
+
211
+ /* Parse it. We are only looking for IO space */
212
+ for (i = 0 ; (i + rs - 1 ) < rlen ; i += rs ) {
213
+ if (be32_to_cpup (ranges + i ) != 1 )
214
+ continue ;
215
+ cbase = be32_to_cpup (ranges + i + 1 );
216
+ size = of_read_number (ranges + i + na + pna , ns );
217
+ pbasep = ranges + i + na ;
218
+ break ;
219
+ }
220
+
221
+ /* Got something ? */
222
+ if (!size || !pbasep ) {
223
+ pr_warn ("ISA: Non-PCI bridge %s has no usable IO range\n" ,
224
+ np -> full_name );
225
+ return ;
226
+ }
227
+
228
+ /* Align size and make sure it's cropped to 64K */
229
+ size = PAGE_ALIGN (size );
230
+ if (size > 0x10000 )
231
+ size = 0x10000 ;
232
+
233
+ /* Map pbase */
234
+ pbase = of_translate_address (np , pbasep );
235
+ if (pbase == OF_BAD_ADDR ) {
236
+ pr_warn ("ISA: Non-PCI bridge %s failed to translate IO base\n" ,
237
+ np -> full_name );
238
+ return ;
239
+ }
240
+
241
+ /* We need page alignment */
242
+ if ((cbase & ~PAGE_MASK ) || (pbase & ~PAGE_MASK )) {
243
+ pr_warn ("ISA: Non-PCI bridge %s has non aligned IO range\n" ,
244
+ np -> full_name );
245
+ return ;
246
+ }
247
+
248
+ /* Got it */
249
+ isa_bridge_devnode = np ;
250
+
251
+ /* Set the global ISA io base to indicate we have an ISA bridge
252
+ * and map it
253
+ */
254
+ isa_io_base = ISA_IO_BASE ;
255
+ __ioremap_at (pbase , (void * )ISA_IO_BASE ,
256
+ size , pgprot_val (pgprot_noncached (__pgprot (0 ))));
257
+
258
+ pr_debug ("ISA: Non-PCI bridge is %s\n" , np -> full_name );
259
+ }
260
+
170
261
/**
171
262
* isa_bridge_find_late - Find and map the ISA IO space upon discovery of
172
263
* a new ISA bridge
0 commit comments