^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for handling the PCIe controller errors on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * HiSilicon HIP SoCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2020 HiSilicon Limited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/ghes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* HISI PCIe controller error definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define HISI_PCIE_ERR_MISC_REGS 33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define HISI_PCIE_LOCAL_VALID_VERSION BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define HISI_PCIE_LOCAL_VALID_SOC_ID BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define HISI_PCIE_LOCAL_VALID_SOCKET_ID BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define HISI_PCIE_LOCAL_VALID_NIMBUS_ID BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define HISI_PCIE_LOCAL_VALID_SUB_MODULE_ID BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define HISI_PCIE_LOCAL_VALID_CORE_ID BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define HISI_PCIE_LOCAL_VALID_PORT_ID BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static guid_t hisi_pcie_sec_guid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Firmware reports the socket port ID where the error occurred. These
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * macros convert that to the core ID and core port ID required by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * ACPI reset method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define HISI_PCIE_PORT_ID(core, v) (((v) >> 1) + ((core) << 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HISI_PCIE_CORE_ID(v) ((v) >> 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define HISI_PCIE_CORE_PORT_ID(v) (((v) & 7) << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct hisi_pcie_error_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u64 val_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u8 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u8 soc_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u8 socket_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u8 nimbus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 sub_module_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 core_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u8 port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 err_severity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u16 err_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 reserv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct hisi_pcie_error_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct notifier_block nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) enum hisi_pcie_submodule_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) HISI_PCIE_SUB_MODULE_ID_AP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) HISI_PCIE_SUB_MODULE_ID_TL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) HISI_PCIE_SUB_MODULE_ID_MAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) HISI_PCIE_SUB_MODULE_ID_DL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) HISI_PCIE_SUB_MODULE_ID_SDI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static const char * const hisi_pcie_sub_module[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [HISI_PCIE_SUB_MODULE_ID_AP] = "AP Layer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [HISI_PCIE_SUB_MODULE_ID_TL] = "TL Layer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) [HISI_PCIE_SUB_MODULE_ID_MAC] = "MAC Layer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) [HISI_PCIE_SUB_MODULE_ID_DL] = "DL Layer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [HISI_PCIE_SUB_MODULE_ID_SDI] = "SDI Layer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) enum hisi_pcie_err_severity {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) HISI_PCIE_ERR_SEV_RECOVERABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) HISI_PCIE_ERR_SEV_FATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) HISI_PCIE_ERR_SEV_CORRECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) HISI_PCIE_ERR_SEV_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static const char * const hisi_pcie_error_sev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) [HISI_PCIE_ERR_SEV_RECOVERABLE] = "recoverable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [HISI_PCIE_ERR_SEV_FATAL] = "fatal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [HISI_PCIE_ERR_SEV_CORRECTED] = "corrected",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [HISI_PCIE_ERR_SEV_NONE] = "none",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const char *hisi_pcie_get_string(const char * const *array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) size_t n, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u32 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) for (index = 0; index < n; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (index == id && array[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return array[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int hisi_pcie_port_reset(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 chip_id, u32 port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) acpi_handle handle = ACPI_HANDLE(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) union acpi_object arg[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct acpi_object_list arg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) acpi_status s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned long long data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) arg[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) arg[0].integer.value = chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) arg[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) arg[1].integer.value = HISI_PCIE_CORE_ID(port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) arg[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) arg[2].integer.value = HISI_PCIE_CORE_PORT_ID(port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) arg_list.count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) arg_list.pointer = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) s = acpi_evaluate_integer(handle, "RST", &arg_list, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (ACPI_FAILURE(s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) dev_err(dev, "No RST method\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dev_err(dev, "Failed to Reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int hisi_pcie_port_do_recovery(struct platform_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 chip_id, u32 port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) acpi_status s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct device *device = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) acpi_handle root_handle = ACPI_HANDLE(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct acpi_pci_root *pci_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct pci_bus *root_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u32 domain, busnr, devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) s = acpi_get_parent(root_handle, &root_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ACPI_FAILURE(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pci_root = acpi_pci_find_root(root_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!pci_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) root_bus = pci_root->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) domain = pci_root->segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) busnr = root_bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) devfn = PCI_DEVFN(port_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pdev = pci_get_domain_bus_and_slot(domain, busnr, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev_info(device, "Fail to get root port %04x:%02x:%02x.%d device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) domain, busnr, PCI_SLOT(devfn), PCI_FUNC(devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) pci_stop_and_remove_bus_device_locked(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (hisi_pcie_port_reset(dev, chip_id, port_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * The initialization time of subordinate devices after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * hot reset is no more than 1s, which is required by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * the PCI spec v5.0 sec 6.6.1. The time will shorten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * if Readiness Notifications mechanisms are used. But
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * wait 1s here to adapt any conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ssleep(1UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* add root port and downstream devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pci_rescan_bus(root_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void hisi_pcie_handle_error(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) const struct hisi_pcie_error_data *edata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int idx, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) const unsigned long valid_bits[] = {BITMAP_FROM_U64(edata->val_bits)};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (edata->val_bits == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dev_warn(dev, "%s: no valid error information\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dev_info(dev, "\nHISI : HIP : PCIe controller error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_SOC_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev_info(dev, "Table version = %d\n", edata->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_SOCKET_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dev_info(dev, "Socket ID = %d\n", edata->socket_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_NIMBUS_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dev_info(dev, "Nimbus ID = %d\n", edata->nimbus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_SUB_MODULE_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev_info(dev, "Sub Module = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) hisi_pcie_get_string(hisi_pcie_sub_module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ARRAY_SIZE(hisi_pcie_sub_module),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) edata->sub_module_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_CORE_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dev_info(dev, "Core ID = core%d\n", edata->core_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_PORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) dev_info(dev, "Port ID = port%d\n", edata->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_ERR_SEVERITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dev_info(dev, "Error severity = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) hisi_pcie_get_string(hisi_pcie_error_sev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ARRAY_SIZE(hisi_pcie_error_sev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) edata->err_severity));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (edata->val_bits & HISI_PCIE_LOCAL_VALID_ERR_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev_info(dev, "Error type = 0x%x\n", edata->err_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_info(dev, "Reg Dump:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) idx = HISI_PCIE_LOCAL_VALID_ERR_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) for_each_set_bit_from(idx, valid_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) HISI_PCIE_LOCAL_VALID_ERR_MISC + HISI_PCIE_ERR_MISC_REGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_info(dev, "ERR_MISC_%d = 0x%x\n", idx - HISI_PCIE_LOCAL_VALID_ERR_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) edata->err_misc[idx - HISI_PCIE_LOCAL_VALID_ERR_MISC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (edata->err_severity != HISI_PCIE_ERR_SEV_RECOVERABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Recovery for the PCIe controller errors, try reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * PCI port for the error recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rc = hisi_pcie_port_do_recovery(pdev, edata->socket_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) HISI_PCIE_PORT_ID(edata->core_id, edata->port_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_info(dev, "fail to do hisi pcie port reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int hisi_pcie_notify_error(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct acpi_hest_generic_data *gdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) const struct hisi_pcie_error_data *error_data = acpi_hest_get_payload(gdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct hisi_pcie_error_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) guid_t err_sec_guid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u8 socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) import_guid(&err_sec_guid, gdata->section_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!guid_equal(&err_sec_guid, &hisi_pcie_sec_guid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) priv = container_of(nb, struct hisi_pcie_error_private, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dev = priv->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (device_property_read_u8(dev, "socket", &socket))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (error_data->socket_id != socket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pdev = container_of(dev, struct platform_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) hisi_pcie_handle_error(pdev, error_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int hisi_pcie_error_handler_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct hisi_pcie_error_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) priv->nb.notifier_call = hisi_pcie_notify_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) priv->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = ghes_register_vendor_record_notifier(&priv->nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "Failed to register hisi pcie controller error handler with apei\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int hisi_pcie_error_handler_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct hisi_pcie_error_private *priv = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ghes_unregister_vendor_record_notifier(&priv->nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static const struct acpi_device_id hisi_pcie_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { "HISI0361", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static struct platform_driver hisi_pcie_error_handler_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .name = "hisi-pcie-error-handler",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .acpi_match_table = hisi_pcie_acpi_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .probe = hisi_pcie_error_handler_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .remove = hisi_pcie_error_handler_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) module_platform_driver(hisi_pcie_error_handler_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) MODULE_DESCRIPTION("HiSilicon HIP PCIe controller error handling driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) MODULE_LICENSE("GPL v2");