efi-init.c (cdd38c5f1ce4398ec58fec95904b75824daab7b5) efi-init.c (8633ef82f101c040427b57d4df7b706261420b94)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Extensible Firmware Interface
4 *
5 * Based on Extensible Firmware Interface Specification version 2.4
6 *
7 * Copyright (C) 2013 - 2015 Linaro Ltd.
8 */

--- 261 unchanged lines hidden (view full) ---

270 pr_info("SCTLR at EFI stub entry : 0x%08x\n", state->sctlr_before_ebs);
271 pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs);
272 pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs);
273 }
274 early_memunmap(state, sizeof(struct efi_arm_entry_state));
275 }
276#endif
277}
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Extensible Firmware Interface
4 *
5 * Based on Extensible Firmware Interface Specification version 2.4
6 *
7 * Copyright (C) 2013 - 2015 Linaro Ltd.
8 */

--- 261 unchanged lines hidden (view full) ---

270 pr_info("SCTLR at EFI stub entry : 0x%08x\n", state->sctlr_before_ebs);
271 pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs);
272 pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs);
273 }
274 early_memunmap(state, sizeof(struct efi_arm_entry_state));
275 }
276#endif
277}
278
279static bool efifb_overlaps_pci_range(const struct of_pci_range *range)
280{
281 u64 fb_base = screen_info.lfb_base;
282
283 if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
284 fb_base |= (u64)(unsigned long)screen_info.ext_lfb_base << 32;
285
286 return fb_base >= range->cpu_addr &&
287 fb_base < (range->cpu_addr + range->size);
288}
289
290static struct device_node *find_pci_overlap_node(void)
291{
292 struct device_node *np;
293
294 for_each_node_by_type(np, "pci") {
295 struct of_pci_range_parser parser;
296 struct of_pci_range range;
297 int err;
298
299 err = of_pci_range_parser_init(&parser, np);
300 if (err) {
301 pr_warn("of_pci_range_parser_init() failed: %d\n", err);
302 continue;
303 }
304
305 for_each_of_pci_range(&parser, &range)
306 if (efifb_overlaps_pci_range(&range))
307 return np;
308 }
309 return NULL;
310}
311
312/*
313 * If the efifb framebuffer is backed by a PCI graphics controller, we have
314 * to ensure that this relation is expressed using a device link when
315 * running in DT mode, or the probe order may be reversed, resulting in a
316 * resource reservation conflict on the memory window that the efifb
317 * framebuffer steals from the PCIe host bridge.
318 */
319static int efifb_add_links(struct fwnode_handle *fwnode)
320{
321 struct device_node *sup_np;
322
323 sup_np = find_pci_overlap_node();
324
325 /*
326 * If there's no PCI graphics controller backing the efifb, we are
327 * done here.
328 */
329 if (!sup_np)
330 return 0;
331
332 fwnode_link_add(fwnode, of_fwnode_handle(sup_np));
333 of_node_put(sup_np);
334
335 return 0;
336}
337
338static const struct fwnode_operations efifb_fwnode_ops = {
339 .add_links = efifb_add_links,
340};
341
342static struct fwnode_handle efifb_fwnode;
343
344static int __init register_gop_device(void)
345{
346 struct platform_device *pd;
347 int err;
348
349 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
350 return 0;
351
352 pd = platform_device_alloc("efi-framebuffer", 0);
353 if (!pd)
354 return -ENOMEM;
355
356 if (IS_ENABLED(CONFIG_PCI)) {
357 fwnode_init(&efifb_fwnode, &efifb_fwnode_ops);
358 pd->dev.fwnode = &efifb_fwnode;
359 }
360
361 err = platform_device_add_data(pd, &screen_info, sizeof(screen_info));
362 if (err)
363 return err;
364
365 return platform_device_add(pd);
366}
367subsys_initcall(register_gop_device);