drm/panel: panel-himax-hx83102: support for csot-pna957qt1-1 MIPI-DSI panel
[drm/drm-misc.git] / drivers / firmware / efi / libstub / pci.c
blob1dccf77958d3a06bf8653420691b0f5d7e36e68a
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * PCI-related functions used by the EFI stub on multiple
4 * architectures.
6 * Copyright 2019 Google, LLC
7 */
9 #include <linux/efi.h>
10 #include <linux/pci.h>
12 #include <asm/efi.h>
14 #include "efistub.h"
16 void efi_pci_disable_bridge_busmaster(void)
18 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
19 efi_handle_t *pci_handle __free(efi_pool) = NULL;
20 unsigned long pci_handle_num;
21 efi_handle_t handle;
22 efi_status_t status;
23 u16 class, command;
25 status = efi_bs_call(locate_handle_buffer, EFI_LOCATE_BY_PROTOCOL,
26 &pci_proto, NULL, &pci_handle_num, &pci_handle);
27 if (status != EFI_SUCCESS) {
28 efi_err("Failed to locate PCI I/O handles\n");
29 return;
32 for_each_efi_handle(handle, pci_handle, pci_handle_num) {
33 efi_pci_io_protocol_t *pci;
34 unsigned long segment_nr, bus_nr, device_nr, func_nr;
36 status = efi_bs_call(handle_protocol, handle, &pci_proto,
37 (void **)&pci);
38 if (status != EFI_SUCCESS)
39 continue;
42 * Disregard devices living on bus 0 - these are not behind a
43 * bridge so no point in disconnecting them from their drivers.
45 status = efi_call_proto(pci, get_location, &segment_nr, &bus_nr,
46 &device_nr, &func_nr);
47 if (status != EFI_SUCCESS || bus_nr == 0)
48 continue;
51 * Don't disconnect VGA controllers so we don't risk losing
52 * access to the framebuffer. Drivers for true PCIe graphics
53 * controllers that are behind a PCIe root port do not use
54 * DMA to implement the GOP framebuffer anyway [although they
55 * may use it in their implementation of Gop->Blt()], and so
56 * disabling DMA in the PCI bridge should not interfere with
57 * normal operation of the device.
59 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
60 PCI_CLASS_DEVICE, 1, &class);
61 if (status != EFI_SUCCESS || class == PCI_CLASS_DISPLAY_VGA)
62 continue;
64 /* Disconnect this handle from all its drivers */
65 efi_bs_call(disconnect_controller, handle, NULL, NULL);
68 for_each_efi_handle(handle, pci_handle, pci_handle_num) {
69 efi_pci_io_protocol_t *pci;
71 status = efi_bs_call(handle_protocol, handle, &pci_proto,
72 (void **)&pci);
73 if (status != EFI_SUCCESS || !pci)
74 continue;
76 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
77 PCI_CLASS_DEVICE, 1, &class);
79 if (status != EFI_SUCCESS || class != PCI_CLASS_BRIDGE_PCI)
80 continue;
82 /* Disable busmastering */
83 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
84 PCI_COMMAND, 1, &command);
85 if (status != EFI_SUCCESS || !(command & PCI_COMMAND_MASTER))
86 continue;
88 command &= ~PCI_COMMAND_MASTER;
89 status = efi_call_proto(pci, pci.write, EfiPciIoWidthUint16,
90 PCI_COMMAND, 1, &command);
91 if (status != EFI_SUCCESS)
92 efi_err("Failed to disable PCI busmastering\n");