Commit 11b31250 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ACPI updates from Rafael Wysocki:
 "These update the ACPICA code in the kernel to upstream version
  20240827, add support for ACPI-based enumeration of interrupt
  controllers on RISC-V along with some related irqchip updates, clean
  up the ACPI device object sysfs interface, add some quirks for
  backlight handling and IRQ overrides, fix assorted issues and clean up
  code.

  Specifics:

   - Check return value in acpi_db_convert_to_package() (Pei Xiao)

   - Detect FACS and allow setting the waking vector on reduced-hardware
     ACPI platforms (Jiaqing Zhao)

   - Allow ACPICA to represent semaphores as integers (Adrien Destugues)

   - Complete CXL 3.0 CXIMS structures support in ACPICA (Zhang Rui)

   - Make ACPICA support SPCR version 4 and add RISC-V SBI Subtype to
     DBG2 (Sia Jee Heng)

   - Implement the Dword_PCC Resource Descriptor Macro in ACPICA (Jose
     Marinho)

   - Correct the typo in struct acpi_mpam_msc_node member (Punit
     Agrawal)

   - Implement ACPI_WARNING_ONCE() and ACPI_ERROR_ONCE() and use them to
     prevent a Stall() violation warning from being printed every time
     this takes place (Vasily Khoruzhick)

   - Allow PCC Data Type in MCTP resource (Adam Young)

   - Fix memory leaks on acpi_ps_get_next_namepath() and
     acpi_ps_get_next_field() failures (Armin Wolf)

   - Add support for supressing leading zeros in hex strings when
     converting them to integers and update integer-to-hex-string
     conversions in ACPICA (Armin Wolf)

   - Add support for Windows 11 22H2 _OSI string (Armin Wolf)

   - Avoid warning for Dump Functions in ACPICA (Adam Lackorzynski)

   - Add extended linear address mode to HMAT MSCIS in ACPICA (Dave
     Jiang)

   - Handle empty connection_node in iasl (Aleksandrs Vinarskis)

   - Allow for more flexibility in _DSM args (Saket Dumbre)

   - Setup for ACPICA release 20240827 (Saket Dumbre)

   - Add ACPI device enumeration support for interrupt controller
     probing including taking dependencies into account (Sunil V L)

   - Implement ACPI-based interrupt controller probing on RISC-V
     (Sunil V L)

   - Add ACPI support for AIA in riscv-intc and add ACPI support to
     riscv-imsic, riscv-aplic, and sifive-plic (Sunil V L)

   - Do not release locks during operation region accesses in the ACPI
     EC driver (Rafael Wysocki)

   - Fix up the _STR handling in the ACPI device object sysfs interface,
     make it represent the device object attributes as an attribute
     group and make it rely on driver core functionality for sysfs
     attrubute management (Thomas Weißschuh)

   - Extend error messages printed to the kernel log when
     acpi_evaluate_dsm() fails to include revision and function number
     (David Wang)

   - Add a new AMDI0015 platform device ID to the ACPi APD driver for
     AMD SoCs (Shyam Sundar S K)

   - Use the driver core for the async probing management in the ACPI
     battery driver (Thomas Weißschuh)

   - Remove redundant initalizations of a local variable to NULL from
     the ACPI battery driver (Ilpo Järvinen)

   - Remove unneeded check in tps68470_pmic_opregion_probe() (Aleksandr
     Mishin)

   - Add support for setting the EPP register through the ACPI CPPC
     sysfs interface if it is in FFH (Mario Limonciello)

   - Fix MASK_VAL() usage in the ACPI CPPC library (Clément Léger)

   - Reduce the log level of a per-CPU message about idle states in the
     ACPI processor driver (Li RongQing)

   - Fix crash in exit_round_robin() in the ACPI processor aggregator
     device (PAD) driver (Seiji Nishikawa)

   - Add force_vendor quirk for Panasonic Toughbook CF-18 in the ACPI
     backlight driver (Hans de Goede)

   - Make the DMI checks related to backlight handling on Lenovo Yoga
     Tab 3 X90F less strict (Hans de Goede)

   - Enforce native backlight handling on Apple MacbookPro9,2 (Esther
     Shimanovich)

   - Add IRQ override quirks for Asus Vivobook Go E1404GAB and MECHREV
     GM7XG0M, and refine the TongFang GMxXGxx quirk (Li Chen, Tamim
     Khan, Werner Sembach)

   - Quirk ASUS ROG M16 to default to S3 sleep (Luke D. Jones)

   - Define and use symbols for device and class name lengths in the
     ACPI bus type code and make the code use strscpy() instead of
     strcpy() in several places (Muhammad Qasim Abdul Majeed)"

* tag 'acpi-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (70 commits)
  ACPI: resource: Add another DMI match for the TongFang GMxXGxx
  ACPI: CPPC: Add support for setting EPP register in FFH
  ACPI: PM: Quirk ASUS ROG M16 to default to S3 sleep
  ACPI: video: Add force_vendor quirk for Panasonic Toughbook CF-18
  ACPI: battery: use driver core managed async probing
  ACPI: button: Use strscpy() instead of strcpy()
  ACPI: resource: Skip IRQ override on Asus Vivobook Go E1404GAB
  ACPI: CPPC: Fix MASK_VAL() usage
  irqchip/sifive-plic: Add ACPI support
  ACPICA: Setup for ACPICA release 20240827
  ACPICA: Allow for more flexibility in _DSM args
  ACPICA: iasl: handle empty connection_node
  ACPICA: HMAT: Add extended linear address mode to MSCIS
  ACPICA: Avoid warning for Dump Functions
  ACPICA: Add support for Windows 11 22H2 _OSI string
  ACPICA: Update integer-to-hex-string conversions
  ACPICA: Add support for supressing leading zeros in hex strings
  ACPICA: Allow for supressing leading zeros when using acpi_ex_convert_to_ascii()
  ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
  ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
  ...
parents 64dd3b6a 3dd2fcf4
Loading
Loading
Loading
Loading
+0 −191
Original line number Diff line number Diff line
@@ -6,28 +6,7 @@
 * Copyright (C) 2014 ARM Ltd.
 */

#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
#include <linux/slab.h>

#ifdef CONFIG_ACPI
/*
 * Try to assign the IRQ number when probing a new device
 */
int pcibios_alloc_irq(struct pci_dev *dev)
{
	if (!acpi_disabled)
		acpi_pci_irq_enable(dev);

	return 0;
}
#endif

/*
 * raw_pci_read/write - Platform-specific PCI config space access.
@@ -61,173 +40,3 @@ int pcibus_to_node(struct pci_bus *bus)
EXPORT_SYMBOL(pcibus_to_node);

#endif

#ifdef CONFIG_ACPI

struct acpi_pci_generic_root_info {
	struct acpi_pci_root_info	common;
	struct pci_config_window	*cfg;	/* config space mapping */
};

int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
{
	struct pci_config_window *cfg = bus->sysdata;
	struct acpi_device *adev = to_acpi_device(cfg->parent);
	struct acpi_pci_root *root = acpi_driver_data(adev);

	return root->segment;
}

int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
{
	struct pci_config_window *cfg;
	struct acpi_device *adev;
	struct device *bus_dev;

	if (acpi_disabled)
		return 0;

	cfg = bridge->bus->sysdata;

	/*
	 * On Hyper-V there is no corresponding ACPI device for a root bridge,
	 * therefore ->parent is set as NULL by the driver. And set 'adev' as
	 * NULL in this case because there is no proper ACPI device.
	 */
	if (!cfg->parent)
		adev = NULL;
	else
		adev = to_acpi_device(cfg->parent);

	bus_dev = &bridge->bus->dev;

	ACPI_COMPANION_SET(&bridge->dev, adev);
	set_dev_node(bus_dev, acpi_get_node(acpi_device_handle(adev)));

	return 0;
}

static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
	struct resource_entry *entry, *tmp;
	int status;

	status = acpi_pci_probe_root_resources(ci);
	resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
		if (!(entry->res->flags & IORESOURCE_WINDOW))
			resource_list_destroy_entry(entry);
	}
	return status;
}

/*
 * Lookup the bus range for the domain in MCFG, and set up config space
 * mapping.
 */
static struct pci_config_window *
pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
{
	struct device *dev = &root->device->dev;
	struct resource *bus_res = &root->secondary;
	u16 seg = root->segment;
	const struct pci_ecam_ops *ecam_ops;
	struct resource cfgres;
	struct acpi_device *adev;
	struct pci_config_window *cfg;
	int ret;

	ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
	if (ret) {
		dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
		return NULL;
	}

	adev = acpi_resource_consumer(&cfgres);
	if (adev)
		dev_info(dev, "ECAM area %pR reserved by %s\n", &cfgres,
			 dev_name(&adev->dev));
	else
		dev_warn(dev, FW_BUG "ECAM area %pR not reserved in ACPI namespace\n",
			 &cfgres);

	cfg = pci_ecam_create(dev, &cfgres, bus_res, ecam_ops);
	if (IS_ERR(cfg)) {
		dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res,
			PTR_ERR(cfg));
		return NULL;
	}

	return cfg;
}

/* release_info: free resources allocated by init_info */
static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
{
	struct acpi_pci_generic_root_info *ri;

	ri = container_of(ci, struct acpi_pci_generic_root_info, common);
	pci_ecam_free(ri->cfg);
	kfree(ci->ops);
	kfree(ri);
}

/* Interface called from ACPI code to setup PCI host controller */
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
	struct acpi_pci_generic_root_info *ri;
	struct pci_bus *bus, *child;
	struct acpi_pci_root_ops *root_ops;
	struct pci_host_bridge *host;

	ri = kzalloc(sizeof(*ri), GFP_KERNEL);
	if (!ri)
		return NULL;

	root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL);
	if (!root_ops) {
		kfree(ri);
		return NULL;
	}

	ri->cfg = pci_acpi_setup_ecam_mapping(root);
	if (!ri->cfg) {
		kfree(ri);
		kfree(root_ops);
		return NULL;
	}

	root_ops->release_info = pci_acpi_generic_release_info;
	root_ops->prepare_resources = pci_acpi_root_prepare_resources;
	root_ops->pci_ops = (struct pci_ops *)&ri->cfg->ops->pci_ops;
	bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg);
	if (!bus)
		return NULL;

	/* If we must preserve the resource configuration, claim now */
	host = pci_find_host_bridge(bus);
	if (host->preserve_config)
		pci_bus_claim_resources(bus);

	/*
	 * Assign whatever was left unassigned. If we didn't claim above,
	 * this will reassign everything.
	 */
	pci_assign_unassigned_root_bus_resources(bus);

	list_for_each_entry(child, &bus->children, node)
		pcie_bus_configure_settings(child);

	return bus;
}

void pcibios_add_bus(struct pci_bus *bus)
{
	acpi_pci_add_bus(bus);
}

void pcibios_remove_bus(struct pci_bus *bus)
{
	acpi_pci_remove_bus(bus);
}

#endif
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ config 32BIT
config RISCV
	def_bool y
	select ACPI_GENERIC_GSI if ACPI
	select ACPI_MCFG if (ACPI && PCI)
	select ACPI_PPTT if ACPI
	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
	select ACPI_SPCR_TABLE if ACPI
@@ -188,6 +189,7 @@ config RISCV
	select OF_EARLY_FLATTREE
	select OF_IRQ
	select PCI_DOMAINS_GENERIC if PCI
	select PCI_ECAM if (ACPI && PCI)
	select PCI_MSI if PCI
	select RISCV_ALTERNATIVE if !XIP_KERNEL
	select RISCV_APLIC
+55 −0
Original line number Diff line number Diff line
@@ -12,8 +12,63 @@

#include <asm-generic/irq.h>

#define INVALID_CONTEXT UINT_MAX

void riscv_set_intc_hwnode_fn(struct fwnode_handle *(*fn)(void));

struct fwnode_handle *riscv_get_intc_hwnode(void);

#ifdef CONFIG_ACPI

enum riscv_irqchip_type {
	ACPI_RISCV_IRQCHIP_INTC		= 0x00,
	ACPI_RISCV_IRQCHIP_IMSIC	= 0x01,
	ACPI_RISCV_IRQCHIP_PLIC		= 0x02,
	ACPI_RISCV_IRQCHIP_APLIC	= 0x03,
};

int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
			    u32 *id, u32 *nr_irqs, u32 *nr_idcs);
struct fwnode_handle *riscv_acpi_get_gsi_domain_id(u32 gsi);
unsigned long acpi_rintc_index_to_hartid(u32 index);
unsigned long acpi_rintc_ext_parent_to_hartid(unsigned int plic_id, unsigned int ctxt_idx);
unsigned int acpi_rintc_get_plic_nr_contexts(unsigned int plic_id);
unsigned int acpi_rintc_get_plic_context(unsigned int plic_id, unsigned int ctxt_idx);
int __init acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res);

#else
static inline int riscv_acpi_get_gsi_info(struct fwnode_handle *fwnode, u32 *gsi_base,
					  u32 *id, u32 *nr_irqs, u32 *nr_idcs)
{
	return 0;
}

static inline unsigned long acpi_rintc_index_to_hartid(u32 index)
{
	return INVALID_HARTID;
}

static inline unsigned long acpi_rintc_ext_parent_to_hartid(unsigned int plic_id,
							    unsigned int ctxt_idx)
{
	return INVALID_HARTID;
}

static inline unsigned int acpi_rintc_get_plic_nr_contexts(unsigned int plic_id)
{
	return INVALID_CONTEXT;
}

static inline unsigned int acpi_rintc_get_plic_context(unsigned int plic_id, unsigned int ctxt_idx)
{
	return INVALID_CONTEXT;
}

static inline int __init acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res)
{
	return 0;
}

#endif /* CONFIG_ACPI */

#endif /* _ASM_RISCV_IRQ_H */
+14 −17
Original line number Diff line number Diff line
@@ -311,29 +311,26 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
#ifdef CONFIG_PCI

/*
 * These interfaces are defined just to enable building ACPI core.
 * TODO: Update it with actual implementation when external interrupt
 * controller support is added in RISC-V ACPI.
 * raw_pci_read/write - Platform-specific PCI config space access.
 */
int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
		 int reg, int len, u32 *val)
int raw_pci_read(unsigned int domain, unsigned int bus,
		 unsigned int devfn, int reg, int len, u32 *val)
{
	return PCIBIOS_DEVICE_NOT_FOUND;
}
	struct pci_bus *b = pci_find_bus(domain, bus);

int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
		  int reg, int len, u32 val)
{
	if (!b)
		return PCIBIOS_DEVICE_NOT_FOUND;
	return b->ops->read(b, devfn, reg, len, val);
}

int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
int raw_pci_write(unsigned int domain, unsigned int bus,
		  unsigned int devfn, int reg, int len, u32 val)
{
	return -1;
}
	struct pci_bus *b = pci_find_bus(domain, bus);

struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
	return NULL;
	if (!b)
		return PCIBIOS_DEVICE_NOT_FOUND;
	return b->ops->write(b, devfn, reg, len, val);
}

#endif	/* CONFIG_PCI */
+2 −2
Original line number Diff line number Diff line
@@ -213,8 +213,8 @@ static int acpi_ac_probe(struct platform_device *pdev)
		return -ENOMEM;

	ac->device = adev;
	strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
	strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
	strscpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
	strscpy(acpi_device_class(adev), ACPI_AC_CLASS);

	platform_set_drvdata(pdev, ac);

Loading