brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · b79b7c9 Raw
83 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#define pr_fmt(fmt) "ACPI: " fmt4 5#include <linux/pci.h>6#include <linux/acpi.h>7#include <acpi/reboot.h>8#include <linux/delay.h>9 10#ifdef CONFIG_PCI11static void acpi_pci_reboot(struct acpi_generic_address *rr, u8 reset_value)12{13	unsigned int devfn;14	struct pci_bus *bus0;15 16	/* The reset register can only live on bus 0. */17	bus0 = pci_find_bus(0, 0);18	if (!bus0)19		return;20	/* Form PCI device/function pair. */21	devfn = PCI_DEVFN((rr->address >> 32) & 0xffff,22			  (rr->address >> 16) & 0xffff);23	pr_debug("Resetting with ACPI PCI RESET_REG.\n");24	/* Write the value that resets us. */25	pci_bus_write_config_byte(bus0, devfn,26			(rr->address & 0xffff), reset_value);27}28#else29static inline void acpi_pci_reboot(struct acpi_generic_address *rr,30				   u8 reset_value)31{32	pr_warn_once("PCI configuration space access is not supported\n");33}34#endif35 36void acpi_reboot(void)37{38	struct acpi_generic_address *rr;39	u8 reset_value;40 41	if (acpi_disabled)42		return;43 44	rr = &acpi_gbl_FADT.reset_register;45 46	/* ACPI reset register was only introduced with v2 of the FADT */47 48	if (acpi_gbl_FADT.header.revision < 2)49		return;50 51	/* Is the reset register supported? The spec says we should be52	 * checking the bit width and bit offset, but Windows ignores53	 * these fields */54	if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))55		return;56 57	reset_value = acpi_gbl_FADT.reset_value;58 59	/* The reset register can only exist in I/O, Memory or PCI config space60	 * on a device on bus 0. */61	switch (rr->space_id) {62	case ACPI_ADR_SPACE_PCI_CONFIG:63		acpi_pci_reboot(rr, reset_value);64		break;65 66	case ACPI_ADR_SPACE_SYSTEM_MEMORY:67	case ACPI_ADR_SPACE_SYSTEM_IO:68		pr_debug("ACPI MEMORY or I/O RESET_REG.\n");69		acpi_reset();70		break;71	}72 73	/*74	 * Some platforms do not shut down immediately after writing to the75	 * ACPI reset register, and this results in racing with the76	 * subsequent reboot mechanism.77	 *78	 * The 15ms delay has been found to be long enough for the system79	 * to reboot on the affected platforms.80	 */81	mdelay(15);82}83