mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 13:29:17 -04:00
Merge tags 'acpi-6.2-rc1' and 'irq-core-2022-12-10' into loongarch-next
LoongArch architecture changes for 6.2 depend on the acpi and irqchip changes to work, so merge them to create a base.
This commit is contained in:
@@ -285,3 +285,13 @@ to bridges between the PCI root and the device, MSIs are disabled.
|
||||
It is also worth checking the device driver to see whether it supports MSIs.
|
||||
For example, it may contain calls to pci_alloc_irq_vectors() with the
|
||||
PCI_IRQ_MSI or PCI_IRQ_MSIX flags.
|
||||
|
||||
|
||||
List of device drivers MSI(-X) APIs
|
||||
===================================
|
||||
|
||||
The PCI/MSI subystem has a dedicated C file for its exported device driver
|
||||
APIs — `drivers/pci/msi/api.c`. The following functions are exported:
|
||||
|
||||
.. kernel-doc:: drivers/pci/msi/api.c
|
||||
:export:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/interrupt-controller/loongarch,cpu-interrupt-controller.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LoongArch CPU Interrupt Controller
|
||||
|
||||
maintainers:
|
||||
- Liu Peibao <liupeibao@loongson.cn>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: loongarch,cpu-interrupt-controller
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- '#interrupt-cells'
|
||||
- interrupt-controller
|
||||
|
||||
examples:
|
||||
- |
|
||||
interrupt-controller {
|
||||
compatible = "loongarch,cpu-interrupt-controller";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
* Mediatek 27xx cirq
|
||||
|
||||
In Mediatek SOCs, the CIRQ is a low power interrupt controller designed to
|
||||
work outside MCUSYS which comprises with Cortex-Ax cores,CCI and GIC.
|
||||
The external interrupts (outside MCUSYS) will feed through CIRQ and connect
|
||||
to GIC in MCUSYS. When CIRQ is enabled, it will record the edge-sensitive
|
||||
interrupts and generate a pulse signal to parent interrupt controller when
|
||||
flush command is executed. With CIRQ, MCUSYS can be completely turned off
|
||||
to improve the system power consumption without losing interrupts.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of
|
||||
- "mediatek,mt2701-cirq" for mt2701 CIRQ
|
||||
- "mediatek,mt8135-cirq" for mt8135 CIRQ
|
||||
- "mediatek,mt8173-cirq" for mt8173 CIRQ
|
||||
and "mediatek,cirq" as a fallback.
|
||||
- interrupt-controller : Identifies the node as an interrupt controller.
|
||||
- #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt.
|
||||
- reg: Physical base address of the cirq registers and length of memory
|
||||
mapped region.
|
||||
- mediatek,ext-irq-range: Identifies external irq number range in different
|
||||
SOCs.
|
||||
|
||||
Example:
|
||||
cirq: interrupt-controller@10204000 {
|
||||
compatible = "mediatek,mt2701-cirq",
|
||||
"mediatek,mtk-cirq";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&sysirq>;
|
||||
reg = <0 0x10204000 0 0x400>;
|
||||
mediatek,ext-irq-start = <32 200>;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/interrupt-controller/mediatek,mtk-cirq.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek System Interrupt Controller
|
||||
|
||||
maintainers:
|
||||
- Youlin Pei <youlin.pei@mediatek.com>
|
||||
|
||||
description:
|
||||
In MediaTek SoCs, the CIRQ is a low power interrupt controller designed to
|
||||
work outside of MCUSYS which comprises with Cortex-Ax cores, CCI and GIC.
|
||||
The external interrupts (outside MCUSYS) will feed through CIRQ and connect
|
||||
to GIC in MCUSYS. When CIRQ is enabled, it will record the edge-sensitive
|
||||
interrupts and generate a pulse signal to parent interrupt controller when
|
||||
flush command is executed. With CIRQ, MCUSYS can be completely turned off
|
||||
to improve the system power consumption without losing interrupts.
|
||||
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- mediatek,mt2701-cirq
|
||||
- mediatek,mt8135-cirq
|
||||
- mediatek,mt8173-cirq
|
||||
- mediatek,mt8192-cirq
|
||||
- const: mediatek,mtk-cirq
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 3
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
mediatek,ext-irq-range:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: First CIRQ interrupt
|
||||
- description: Last CIRQ interrupt
|
||||
description:
|
||||
Identifies the range of external interrupts in different SoCs
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#interrupt-cells'
|
||||
- interrupt-controller
|
||||
- mediatek,ext-irq-range
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
cirq: interrupt-controller@10204000 {
|
||||
compatible = "mediatek,mt2701-cirq", "mediatek,mtk-cirq";
|
||||
reg = <0x10204000 0x400>;
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-controller;
|
||||
interrupt-parent = <&sysirq>;
|
||||
mediatek,ext-irq-range = <32 200>;
|
||||
};
|
||||
@@ -13,6 +13,7 @@
|
||||
#define pr_fmt(fmt) "ACPI: " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/efi-bgrt.h>
|
||||
@@ -411,3 +412,108 @@ void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
|
||||
{
|
||||
memblock_mark_nomap(addr, size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_FFH
|
||||
/*
|
||||
* Implements ARM64 specific callbacks to support ACPI FFH Operation Region as
|
||||
* specified in https://developer.arm.com/docs/den0048/latest
|
||||
*/
|
||||
struct acpi_ffh_data {
|
||||
struct acpi_ffh_info info;
|
||||
void (*invoke_ffh_fn)(unsigned long a0, unsigned long a1,
|
||||
unsigned long a2, unsigned long a3,
|
||||
unsigned long a4, unsigned long a5,
|
||||
unsigned long a6, unsigned long a7,
|
||||
struct arm_smccc_res *args,
|
||||
struct arm_smccc_quirk *res);
|
||||
void (*invoke_ffh64_fn)(const struct arm_smccc_1_2_regs *args,
|
||||
struct arm_smccc_1_2_regs *res);
|
||||
};
|
||||
|
||||
int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt)
|
||||
{
|
||||
enum arm_smccc_conduit conduit;
|
||||
struct acpi_ffh_data *ffh_ctxt;
|
||||
|
||||
ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL);
|
||||
if (!ffh_ctxt)
|
||||
return -ENOMEM;
|
||||
|
||||
if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
conduit = arm_smccc_1_1_get_conduit();
|
||||
if (conduit == SMCCC_CONDUIT_NONE) {
|
||||
pr_err("%s: invalid SMCCC conduit\n", __func__);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (conduit == SMCCC_CONDUIT_SMC) {
|
||||
ffh_ctxt->invoke_ffh_fn = __arm_smccc_smc;
|
||||
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_smc;
|
||||
} else {
|
||||
ffh_ctxt->invoke_ffh_fn = __arm_smccc_hvc;
|
||||
ffh_ctxt->invoke_ffh64_fn = arm_smccc_1_2_hvc;
|
||||
}
|
||||
|
||||
memcpy(ffh_ctxt, handler_ctxt, sizeof(ffh_ctxt->info));
|
||||
|
||||
*region_ctxt = ffh_ctxt;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static bool acpi_ffh_smccc_owner_allowed(u32 fid)
|
||||
{
|
||||
int owner = ARM_SMCCC_OWNER_NUM(fid);
|
||||
|
||||
if (owner == ARM_SMCCC_OWNER_STANDARD ||
|
||||
owner == ARM_SMCCC_OWNER_SIP || owner == ARM_SMCCC_OWNER_OEM)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int acpi_ffh_address_space_arch_handler(acpi_integer *value, void *region_context)
|
||||
{
|
||||
int ret = 0;
|
||||
struct acpi_ffh_data *ffh_ctxt = region_context;
|
||||
|
||||
if (ffh_ctxt->info.offset == 0) {
|
||||
/* SMC/HVC 32bit call */
|
||||
struct arm_smccc_res res;
|
||||
u32 a[8] = { 0 }, *ptr = (u32 *)value;
|
||||
|
||||
if (!ARM_SMCCC_IS_FAST_CALL(*ptr) || ARM_SMCCC_IS_64(*ptr) ||
|
||||
!acpi_ffh_smccc_owner_allowed(*ptr) ||
|
||||
ffh_ctxt->info.length > 32) {
|
||||
ret = AE_ERROR;
|
||||
} else {
|
||||
int idx, len = ffh_ctxt->info.length >> 2;
|
||||
|
||||
for (idx = 0; idx < len; idx++)
|
||||
a[idx] = *(ptr + idx);
|
||||
|
||||
ffh_ctxt->invoke_ffh_fn(a[0], a[1], a[2], a[3], a[4],
|
||||
a[5], a[6], a[7], &res, NULL);
|
||||
memcpy(value, &res, sizeof(res));
|
||||
}
|
||||
|
||||
} else if (ffh_ctxt->info.offset == 1) {
|
||||
/* SMC/HVC 64bit call */
|
||||
struct arm_smccc_1_2_regs *r = (struct arm_smccc_1_2_regs *)value;
|
||||
|
||||
if (!ARM_SMCCC_IS_FAST_CALL(r->a0) || !ARM_SMCCC_IS_64(r->a0) ||
|
||||
!acpi_ffh_smccc_owner_allowed(r->a0) ||
|
||||
ffh_ctxt->info.length > sizeof(*r)) {
|
||||
ret = AE_ERROR;
|
||||
} else {
|
||||
ffh_ctxt->invoke_ffh64_fn(r, r);
|
||||
memcpy(value, r, ffh_ctxt->info.length);
|
||||
}
|
||||
} else {
|
||||
ret = AE_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_FFH */
|
||||
|
||||
@@ -187,9 +187,9 @@ static int aml_nfw_add(struct acpi_device *device)
|
||||
return aml_nfw_add_global_handler();
|
||||
}
|
||||
|
||||
static int aml_nfw_remove(struct acpi_device *device)
|
||||
static void aml_nfw_remove(struct acpi_device *device)
|
||||
{
|
||||
return aml_nfw_remove_global_handler();
|
||||
aml_nfw_remove_global_handler();
|
||||
}
|
||||
|
||||
static const struct acpi_device_id aml_nfw_ids[] = {
|
||||
|
||||
@@ -31,148 +31,6 @@ static inline bool acpi_has_cpu_in_madt(void)
|
||||
|
||||
extern struct list_head acpi_wakeup_device_list;
|
||||
|
||||
/*
|
||||
* Temporary definitions until the core ACPICA code gets updated (see
|
||||
* 1656837932-18257-1-git-send-email-lvjianmin@loongson.cn and its
|
||||
* follow-ups for the "rationale").
|
||||
*
|
||||
* Once the "legal reasons" are cleared and that the code is merged,
|
||||
* this can be dropped entierely.
|
||||
*/
|
||||
#if (ACPI_CA_VERSION == 0x20220331 && !defined(LOONGARCH_ACPICA_EXT))
|
||||
|
||||
#define LOONGARCH_ACPICA_EXT 1
|
||||
|
||||
#define ACPI_MADT_TYPE_CORE_PIC 17
|
||||
#define ACPI_MADT_TYPE_LIO_PIC 18
|
||||
#define ACPI_MADT_TYPE_HT_PIC 19
|
||||
#define ACPI_MADT_TYPE_EIO_PIC 20
|
||||
#define ACPI_MADT_TYPE_MSI_PIC 21
|
||||
#define ACPI_MADT_TYPE_BIO_PIC 22
|
||||
#define ACPI_MADT_TYPE_LPC_PIC 23
|
||||
|
||||
/* Values for Version field above */
|
||||
|
||||
enum acpi_madt_core_pic_version {
|
||||
ACPI_MADT_CORE_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_CORE_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_CORE_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_lio_pic_version {
|
||||
ACPI_MADT_LIO_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_LIO_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_LIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_eio_pic_version {
|
||||
ACPI_MADT_EIO_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_EIO_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_EIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_ht_pic_version {
|
||||
ACPI_MADT_HT_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_HT_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_HT_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_bio_pic_version {
|
||||
ACPI_MADT_BIO_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_BIO_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_BIO_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_msi_pic_version {
|
||||
ACPI_MADT_MSI_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_MSI_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_MSI_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
enum acpi_madt_lpc_pic_version {
|
||||
ACPI_MADT_LPC_PIC_VERSION_NONE = 0,
|
||||
ACPI_MADT_LPC_PIC_VERSION_V1 = 1,
|
||||
ACPI_MADT_LPC_PIC_VERSION_RESERVED = 2 /* 2 and greater are reserved */
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/* Core Interrupt Controller */
|
||||
|
||||
struct acpi_madt_core_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u32 processor_id;
|
||||
u32 core_id;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/* Legacy I/O Interrupt Controller */
|
||||
|
||||
struct acpi_madt_lio_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u64 address;
|
||||
u16 size;
|
||||
u8 cascade[2];
|
||||
u32 cascade_map[2];
|
||||
};
|
||||
|
||||
/* Extend I/O Interrupt Controller */
|
||||
|
||||
struct acpi_madt_eio_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u8 cascade;
|
||||
u8 node;
|
||||
u64 node_map;
|
||||
};
|
||||
|
||||
/* HT Interrupt Controller */
|
||||
|
||||
struct acpi_madt_ht_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u64 address;
|
||||
u16 size;
|
||||
u8 cascade[8];
|
||||
};
|
||||
|
||||
/* Bridge I/O Interrupt Controller */
|
||||
|
||||
struct acpi_madt_bio_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u64 address;
|
||||
u16 size;
|
||||
u16 id;
|
||||
u16 gsi_base;
|
||||
};
|
||||
|
||||
/* MSI Interrupt Controller */
|
||||
|
||||
struct acpi_madt_msi_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u64 msg_address;
|
||||
u32 start;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
/* LPC Interrupt Controller */
|
||||
|
||||
struct acpi_madt_lpc_pic {
|
||||
struct acpi_subtable_header header;
|
||||
u8 version;
|
||||
u64 address;
|
||||
u16 size;
|
||||
u8 cascade;
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !CONFIG_ACPI */
|
||||
|
||||
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
|
||||
|
||||
@@ -93,7 +93,7 @@ int liointc_acpi_init(struct irq_domain *parent,
|
||||
int eiointc_acpi_init(struct irq_domain *parent,
|
||||
struct acpi_madt_eio_pic *acpi_eiointc);
|
||||
|
||||
struct irq_domain *htvec_acpi_init(struct irq_domain *parent,
|
||||
int htvec_acpi_init(struct irq_domain *parent,
|
||||
struct acpi_madt_ht_pic *acpi_htvec);
|
||||
int pch_lpc_acpi_init(struct irq_domain *parent,
|
||||
struct acpi_madt_lpc_pic *acpi_pchlpc);
|
||||
|
||||
@@ -447,21 +447,18 @@ static void pseries_msi_ops_msi_free(struct irq_domain *domain,
|
||||
* RTAS can not disable one MSI at a time. It's all or nothing. Do it
|
||||
* at the end after all IRQs have been freed.
|
||||
*/
|
||||
static void pseries_msi_domain_free_irqs(struct irq_domain *domain,
|
||||
struct device *dev)
|
||||
static void pseries_msi_post_free(struct irq_domain *domain, struct device *dev)
|
||||
{
|
||||
if (WARN_ON_ONCE(!dev_is_pci(dev)))
|
||||
return;
|
||||
|
||||
__msi_domain_free_irqs(domain, dev);
|
||||
|
||||
rtas_disable_msi(to_pci_dev(dev));
|
||||
}
|
||||
|
||||
static struct msi_domain_ops pseries_pci_msi_domain_ops = {
|
||||
.msi_prepare = pseries_msi_ops_prepare,
|
||||
.msi_free = pseries_msi_ops_msi_free,
|
||||
.domain_free_irqs = pseries_msi_domain_free_irqs,
|
||||
.msi_post_free = pseries_msi_post_free,
|
||||
};
|
||||
|
||||
static void pseries_msi_shutdown(struct irq_data *d)
|
||||
|
||||
@@ -381,7 +381,6 @@ config UML_PCI_OVER_VIRTIO
|
||||
select UML_IOMEM_EMULATION
|
||||
select UML_DMA_EMULATION
|
||||
select PCI_MSI
|
||||
select PCI_MSI_IRQ_DOMAIN
|
||||
select PCI_LOCKLESS_CONFIG
|
||||
|
||||
config UML_PCI_OVER_VIRTIO_DEVICE_ID
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/* Generic PCI */
|
||||
#include <asm-generic/pci.h>
|
||||
|
||||
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
/*
|
||||
* This is a bit of an annoying hack, and it assumes we only have
|
||||
* the virt-pci (if anything). Which is true, but still.
|
||||
|
||||
@@ -1109,7 +1109,6 @@ config X86_LOCAL_APIC
|
||||
def_bool y
|
||||
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI
|
||||
select IRQ_DOMAIN_HIERARCHY
|
||||
select PCI_MSI_IRQ_DOMAIN if PCI_MSI
|
||||
|
||||
config X86_IO_APIC
|
||||
def_bool y
|
||||
|
||||
9
arch/x86/include/asm/hyperv_timer.h
Normal file
9
arch/x86/include/asm/hyperv_timer.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_X86_HYPERV_TIMER_H
|
||||
#define _ASM_X86_HYPERV_TIMER_H
|
||||
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define hv_get_raw_timer() rdtsc_ordered()
|
||||
|
||||
#endif
|
||||
@@ -44,10 +44,6 @@ extern int irq_remapping_reenable(int);
|
||||
extern int irq_remap_enable_fault_handling(void);
|
||||
extern void panic_if_irq_remap(const char *msg);
|
||||
|
||||
/* Create PCI MSI/MSIx irqdomain, use @parent as the parent irqdomain. */
|
||||
extern struct irq_domain *
|
||||
arch_create_remap_msi_irq_domain(struct irq_domain *par, const char *n, int id);
|
||||
|
||||
/* Get parent irqdomain for interrupt remapping irqdomain */
|
||||
static inline struct irq_domain *arch_get_ir_parent_domain(void)
|
||||
{
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
enum {
|
||||
/* Allocate contiguous CPU vectors */
|
||||
X86_IRQ_ALLOC_CONTIGUOUS_VECTORS = 0x1,
|
||||
X86_IRQ_ALLOC_LEGACY = 0x2,
|
||||
X86_IRQ_ALLOC_LEGACY = 0x1,
|
||||
};
|
||||
|
||||
extern int x86_fwspec_is_ioapic(struct irq_fwspec *fwspec);
|
||||
|
||||
@@ -19,8 +19,6 @@ typedef int (*hyperv_fill_flush_list_func)(
|
||||
struct hv_guest_mapping_flush_list *flush,
|
||||
void *data);
|
||||
|
||||
#define hv_get_raw_timer() rdtsc_ordered()
|
||||
|
||||
void hyperv_vector_handler(struct pt_regs *regs);
|
||||
|
||||
#if IS_ENABLED(CONFIG_HYPERV)
|
||||
|
||||
@@ -62,4 +62,10 @@ typedef struct x86_msi_addr_hi {
|
||||
struct msi_msg;
|
||||
u32 x86_msi_msg_get_destid(struct msi_msg *msg, bool extid);
|
||||
|
||||
#define X86_VECTOR_MSI_FLAGS_SUPPORTED \
|
||||
(MSI_GENERIC_FLAGS_MASK | MSI_FLAG_PCI_MSIX | MSI_FLAG_PCI_MSIX_ALLOC_DYN)
|
||||
|
||||
#define X86_VECTOR_MSI_FLAGS_REQUIRED \
|
||||
(MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS)
|
||||
|
||||
#endif /* _ASM_X86_MSI_H */
|
||||
|
||||
@@ -21,7 +21,7 @@ struct pci_sysdata {
|
||||
#ifdef CONFIG_X86_64
|
||||
void *iommu; /* IOMMU private data */
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
void *fwnode; /* IRQ domain for MSI assignment */
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_VMD)
|
||||
@@ -52,7 +52,7 @@ static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
|
||||
{
|
||||
return to_pci_sysdata(bus)->fwnode;
|
||||
@@ -92,6 +92,7 @@ void pcibios_scan_root(int bus);
|
||||
struct irq_routing_table *pcibios_get_irq_routing_table(void);
|
||||
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
|
||||
|
||||
bool pci_dev_has_default_msi_parent_domain(struct pci_dev *dev);
|
||||
|
||||
#define HAVE_PCI_MMAP
|
||||
#define arch_can_pci_mmap_wc() pat_enabled()
|
||||
|
||||
@@ -142,70 +142,139 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
|
||||
* which implement the MSI or MSI-X Capability Structure.
|
||||
/**
|
||||
* pci_dev_has_default_msi_parent_domain - Check whether the device has the default
|
||||
* MSI parent domain associated
|
||||
* @dev: Pointer to the PCI device
|
||||
*/
|
||||
static struct irq_chip pci_msi_controller = {
|
||||
.name = "PCI-MSI",
|
||||
.irq_unmask = pci_msi_unmask_irq,
|
||||
.irq_mask = pci_msi_mask_irq,
|
||||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.irq_set_affinity = msi_set_affinity,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE |
|
||||
IRQCHIP_AFFINITY_PRE_STARTUP,
|
||||
};
|
||||
|
||||
int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
|
||||
msi_alloc_info_t *arg)
|
||||
bool pci_dev_has_default_msi_parent_domain(struct pci_dev *dev)
|
||||
{
|
||||
init_irq_alloc_info(arg, NULL);
|
||||
if (to_pci_dev(dev)->msix_enabled) {
|
||||
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
|
||||
} else {
|
||||
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
|
||||
arg->flags |= X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
|
||||
struct irq_domain *domain = dev_get_msi_domain(&dev->dev);
|
||||
|
||||
if (!domain)
|
||||
domain = dev_get_msi_domain(&dev->bus->dev);
|
||||
if (!domain)
|
||||
return false;
|
||||
|
||||
return domain == x86_vector_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_msi_prepare - Setup of msi_alloc_info_t for allocations
|
||||
* @domain: The domain for which this setup happens
|
||||
* @dev: The device for which interrupts are allocated
|
||||
* @nvec: The number of vectors to allocate
|
||||
* @alloc: The allocation info structure to initialize
|
||||
*
|
||||
* This function is to be used for all types of MSI domains above the x86
|
||||
* vector domain and any intermediates. It is always invoked from the
|
||||
* top level interrupt domain. The domain specific allocation
|
||||
* functionality is determined via the @domain's bus token which allows to
|
||||
* map the X86 specific allocation type.
|
||||
*/
|
||||
static int x86_msi_prepare(struct irq_domain *domain, struct device *dev,
|
||||
int nvec, msi_alloc_info_t *alloc)
|
||||
{
|
||||
struct msi_domain_info *info = domain->host_data;
|
||||
|
||||
init_irq_alloc_info(alloc, NULL);
|
||||
|
||||
switch (info->bus_token) {
|
||||
case DOMAIN_BUS_PCI_DEVICE_MSI:
|
||||
alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
|
||||
return 0;
|
||||
case DOMAIN_BUS_PCI_DEVICE_MSIX:
|
||||
case DOMAIN_BUS_PCI_DEVICE_IMS:
|
||||
alloc->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_init_dev_msi_info - Domain info setup for MSI domains
|
||||
* @dev: The device for which the domain should be created
|
||||
* @domain: The (root) domain providing this callback
|
||||
* @real_parent: The real parent domain of the to initialize domain
|
||||
* @info: The domain info for the to initialize domain
|
||||
*
|
||||
* This function is to be used for all types of MSI domains above the x86
|
||||
* vector domain and any intermediates. The domain specific functionality
|
||||
* is determined via the @real_parent.
|
||||
*/
|
||||
static bool x86_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
|
||||
struct irq_domain *real_parent, struct msi_domain_info *info)
|
||||
{
|
||||
const struct msi_parent_ops *pops = real_parent->msi_parent_ops;
|
||||
|
||||
/* MSI parent domain specific settings */
|
||||
switch (real_parent->bus_token) {
|
||||
case DOMAIN_BUS_ANY:
|
||||
/* Only the vector domain can have the ANY token */
|
||||
if (WARN_ON_ONCE(domain != real_parent))
|
||||
return false;
|
||||
info->chip->irq_set_affinity = msi_set_affinity;
|
||||
/* See msi_set_affinity() for the gory details */
|
||||
info->flags |= MSI_FLAG_NOMASK_QUIRK;
|
||||
break;
|
||||
case DOMAIN_BUS_DMAR:
|
||||
case DOMAIN_BUS_AMDVI:
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Is the target supported? */
|
||||
switch(info->bus_token) {
|
||||
case DOMAIN_BUS_PCI_DEVICE_MSI:
|
||||
case DOMAIN_BUS_PCI_DEVICE_MSIX:
|
||||
break;
|
||||
case DOMAIN_BUS_PCI_DEVICE_IMS:
|
||||
if (!(pops->supported_flags & MSI_FLAG_PCI_IMS))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask out the domain specific MSI feature flags which are not
|
||||
* supported by the real parent.
|
||||
*/
|
||||
info->flags &= pops->supported_flags;
|
||||
/* Enforce the required flags */
|
||||
info->flags |= X86_VECTOR_MSI_FLAGS_REQUIRED;
|
||||
|
||||
/* This is always invoked from the top level MSI domain! */
|
||||
info->ops->msi_prepare = x86_msi_prepare;
|
||||
|
||||
info->chip->irq_ack = irq_chip_ack_parent;
|
||||
info->chip->irq_retrigger = irq_chip_retrigger_hierarchy;
|
||||
info->chip->flags |= IRQCHIP_SKIP_SET_WAKE |
|
||||
IRQCHIP_AFFINITY_PRE_STARTUP;
|
||||
|
||||
info->handler = handle_edge_irq;
|
||||
info->handler_name = "edge";
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_msi_prepare);
|
||||
|
||||
static struct msi_domain_ops pci_msi_domain_ops = {
|
||||
.msi_prepare = pci_msi_prepare,
|
||||
};
|
||||
|
||||
static struct msi_domain_info pci_msi_domain_info = {
|
||||
.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
|
||||
MSI_FLAG_PCI_MSIX,
|
||||
.ops = &pci_msi_domain_ops,
|
||||
.chip = &pci_msi_controller,
|
||||
.handler = handle_edge_irq,
|
||||
.handler_name = "edge",
|
||||
static const struct msi_parent_ops x86_vector_msi_parent_ops = {
|
||||
.supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED,
|
||||
.init_dev_msi_info = x86_init_dev_msi_info,
|
||||
};
|
||||
|
||||
struct irq_domain * __init native_create_pci_msi_domain(void)
|
||||
{
|
||||
struct fwnode_handle *fn;
|
||||
struct irq_domain *d;
|
||||
|
||||
if (disable_apic)
|
||||
return NULL;
|
||||
|
||||
fn = irq_domain_alloc_named_fwnode("PCI-MSI");
|
||||
if (!fn)
|
||||
return NULL;
|
||||
|
||||
d = pci_msi_create_irq_domain(fn, &pci_msi_domain_info,
|
||||
x86_vector_domain);
|
||||
if (!d) {
|
||||
irq_domain_free_fwnode(fn);
|
||||
pr_warn("Failed to initialize PCI-MSI irqdomain.\n");
|
||||
} else {
|
||||
d->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
|
||||
}
|
||||
return d;
|
||||
x86_vector_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
|
||||
x86_vector_domain->msi_parent_ops = &x86_vector_msi_parent_ops;
|
||||
return x86_vector_domain;
|
||||
}
|
||||
|
||||
void __init x86_create_pci_msi_domain(void)
|
||||
@@ -213,41 +282,19 @@ void __init x86_create_pci_msi_domain(void)
|
||||
x86_pci_msi_default_domain = x86_init.irqs.create_pci_msi_domain();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IRQ_REMAP
|
||||
static struct irq_chip pci_msi_ir_controller = {
|
||||
.name = "IR-PCI-MSI",
|
||||
.irq_unmask = pci_msi_unmask_irq,
|
||||
.irq_mask = pci_msi_mask_irq,
|
||||
.irq_ack = irq_chip_ack_parent,
|
||||
.irq_retrigger = irq_chip_retrigger_hierarchy,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE |
|
||||
IRQCHIP_AFFINITY_PRE_STARTUP,
|
||||
};
|
||||
|
||||
static struct msi_domain_info pci_msi_ir_domain_info = {
|
||||
.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
|
||||
MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
|
||||
.ops = &pci_msi_domain_ops,
|
||||
.chip = &pci_msi_ir_controller,
|
||||
.handler = handle_edge_irq,
|
||||
.handler_name = "edge",
|
||||
};
|
||||
|
||||
struct irq_domain *arch_create_remap_msi_irq_domain(struct irq_domain *parent,
|
||||
const char *name, int id)
|
||||
/* Keep around for hyperV */
|
||||
int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
|
||||
msi_alloc_info_t *arg)
|
||||
{
|
||||
struct fwnode_handle *fn;
|
||||
struct irq_domain *d;
|
||||
init_irq_alloc_info(arg, NULL);
|
||||
|
||||
fn = irq_domain_alloc_named_id_fwnode(name, id);
|
||||
if (!fn)
|
||||
return NULL;
|
||||
d = pci_msi_create_irq_domain(fn, &pci_msi_ir_domain_info, parent);
|
||||
if (!d)
|
||||
irq_domain_free_fwnode(fn);
|
||||
return d;
|
||||
if (to_pci_dev(dev)->msix_enabled)
|
||||
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
|
||||
else
|
||||
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
EXPORT_SYMBOL_GPL(pci_msi_prepare);
|
||||
|
||||
#ifdef CONFIG_DMAR_TABLE
|
||||
/*
|
||||
|
||||
@@ -539,10 +539,6 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
|
||||
if (disable_apic)
|
||||
return -ENXIO;
|
||||
|
||||
/* Currently vector allocator can't guarantee contiguous allocations */
|
||||
if ((info->flags & X86_IRQ_ALLOC_CONTIGUOUS_VECTORS) && nr_irqs > 1)
|
||||
return -ENOSYS;
|
||||
|
||||
/*
|
||||
* Catch any attempt to touch the cascade interrupt on a PIC
|
||||
* equipped system.
|
||||
|
||||
@@ -183,13 +183,12 @@ static int xo15_sci_add(struct acpi_device *device)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int xo15_sci_remove(struct acpi_device *device)
|
||||
static void xo15_sci_remove(struct acpi_device *device)
|
||||
{
|
||||
acpi_disable_gpe(NULL, xo15_sci_gpe);
|
||||
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
|
||||
cancel_work_sync(&sci_work);
|
||||
sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -564,6 +564,16 @@ config ACPI_PCC
|
||||
Enable this feature if you want to set up and install the PCC Address
|
||||
Space handler to handle PCC OpRegion in the firmware.
|
||||
|
||||
config ACPI_FFH
|
||||
bool "ACPI FFH Address Space"
|
||||
default n
|
||||
help
|
||||
The FFH(Fixed Function Hardware) Address Space also referred as FFH
|
||||
Operation Region allows to define platform specific opregion.
|
||||
|
||||
Enable this feature if you want to set up and install the FFH Address
|
||||
Space handler to handle FFH OpRegion in the firmware.
|
||||
|
||||
source "drivers/acpi/pmic/Kconfig"
|
||||
|
||||
config ACPI_VIOT
|
||||
|
||||
@@ -68,6 +68,7 @@ acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
|
||||
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
|
||||
acpi-$(CONFIG_ACPI_PRMT) += prmt.o
|
||||
acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o
|
||||
acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o
|
||||
|
||||
# Address translation
|
||||
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o
|
||||
|
||||
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("ACPI AC Adapter Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int acpi_ac_add(struct acpi_device *device);
|
||||
static int acpi_ac_remove(struct acpi_device *device);
|
||||
static void acpi_ac_remove(struct acpi_device *device);
|
||||
static void acpi_ac_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
static const struct acpi_device_id ac_device_ids[] = {
|
||||
@@ -288,12 +288,12 @@ static int acpi_ac_resume(struct device *dev)
|
||||
#define acpi_ac_resume NULL
|
||||
#endif
|
||||
|
||||
static int acpi_ac_remove(struct acpi_device *device)
|
||||
static void acpi_ac_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_ac *ac = NULL;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
ac = acpi_driver_data(device);
|
||||
|
||||
@@ -301,8 +301,6 @@ static int acpi_ac_remove(struct acpi_device *device)
|
||||
unregister_acpi_notifier(&ac->battery_nb);
|
||||
|
||||
kfree(ac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init acpi_ac_init(void)
|
||||
|
||||
55
drivers/acpi/acpi_ffh.c
Normal file
55
drivers/acpi/acpi_ffh.c
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Author: Sudeep Holla <sudeep.holla@arm.com>
|
||||
* Copyright 2022 Arm Limited
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
|
||||
static struct acpi_ffh_info ffh_ctx;
|
||||
|
||||
int __weak acpi_ffh_address_space_arch_setup(void *handler_ctxt,
|
||||
void **region_ctxt)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int __weak acpi_ffh_address_space_arch_handler(acpi_integer *value,
|
||||
void *region_context)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
acpi_ffh_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
void *handler_context, void **region_context)
|
||||
{
|
||||
return acpi_ffh_address_space_arch_setup(handler_context,
|
||||
region_context);
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
acpi_ffh_address_space_handler(u32 function, acpi_physical_address addr,
|
||||
u32 bits, acpi_integer *value,
|
||||
void *handler_context, void *region_context)
|
||||
{
|
||||
return acpi_ffh_address_space_arch_handler(value, region_context);
|
||||
}
|
||||
|
||||
void __init acpi_init_ffh(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
|
||||
ACPI_ADR_SPACE_FIXED_HARDWARE,
|
||||
&acpi_ffh_address_space_handler,
|
||||
&acpi_ffh_address_space_setup,
|
||||
&ffh_ctx);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_alert("OperationRegion handler could not be installed\n");
|
||||
}
|
||||
@@ -287,7 +287,7 @@ static ssize_t rrtime_store(struct device *dev,
|
||||
static ssize_t rrtime_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time);
|
||||
return sysfs_emit(buf, "%d\n", round_robin_time);
|
||||
}
|
||||
static DEVICE_ATTR_RW(rrtime);
|
||||
|
||||
@@ -309,7 +309,7 @@ static ssize_t idlepct_store(struct device *dev,
|
||||
static ssize_t idlepct_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct);
|
||||
return sysfs_emit(buf, "%d\n", idle_pct);
|
||||
}
|
||||
static DEVICE_ATTR_RW(idlepct);
|
||||
|
||||
@@ -449,7 +449,7 @@ static int acpi_pad_add(struct acpi_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_pad_remove(struct acpi_device *device)
|
||||
static void acpi_pad_remove(struct acpi_device *device)
|
||||
{
|
||||
mutex_lock(&isolated_cpus_lock);
|
||||
acpi_pad_idle_cpus(0);
|
||||
@@ -458,7 +458,6 @@ static int acpi_pad_remove(struct acpi_device *device)
|
||||
acpi_remove_notify_handler(device->handle,
|
||||
ACPI_DEVICE_NOTIFY, acpi_pad_notify);
|
||||
acpi_pad_remove_sysfs(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id pad_device_ids[] = {
|
||||
|
||||
@@ -53,6 +53,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
struct pcc_data *data;
|
||||
struct acpi_pcc_info *ctx = handler_context;
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
static acpi_status ret;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
@@ -69,23 +70,35 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
if (IS_ERR(data->pcc_chan)) {
|
||||
pr_err("Failed to find PCC channel for subspace %d\n",
|
||||
ctx->subspace_id);
|
||||
kfree(data);
|
||||
return AE_NOT_FOUND;
|
||||
ret = AE_NOT_FOUND;
|
||||
goto err_free_data;
|
||||
}
|
||||
|
||||
pcc_chan = data->pcc_chan;
|
||||
if (!pcc_chan->mchan->mbox->txdone_irq) {
|
||||
pr_err("This channel-%d does not support interrupt.\n",
|
||||
ctx->subspace_id);
|
||||
ret = AE_SUPPORT;
|
||||
goto err_free_channel;
|
||||
}
|
||||
data->pcc_comm_addr = acpi_os_ioremap(pcc_chan->shmem_base_addr,
|
||||
pcc_chan->shmem_size);
|
||||
if (!data->pcc_comm_addr) {
|
||||
pr_err("Failed to ioremap PCC comm region mem for %d\n",
|
||||
ctx->subspace_id);
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
kfree(data);
|
||||
return AE_NO_MEMORY;
|
||||
ret = AE_NO_MEMORY;
|
||||
goto err_free_channel;
|
||||
}
|
||||
|
||||
*region_context = data;
|
||||
return AE_OK;
|
||||
|
||||
err_free_channel:
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
err_free_data:
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
@@ -106,19 +119,17 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
||||
if (ret < 0)
|
||||
return AE_ERROR;
|
||||
|
||||
if (data->pcc_chan->mchan->mbox->txdone_irq) {
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
}
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
}
|
||||
|
||||
mbox_chan_txdone(data->pcc_chan->mchan, ret);
|
||||
|
||||
@@ -86,7 +86,7 @@ static DEFINE_MUTEX(register_count_mutex);
|
||||
static DEFINE_MUTEX(video_list_lock);
|
||||
static LIST_HEAD(video_bus_head);
|
||||
static int acpi_video_bus_add(struct acpi_device *device);
|
||||
static int acpi_video_bus_remove(struct acpi_device *device);
|
||||
static void acpi_video_bus_remove(struct acpi_device *device);
|
||||
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
|
||||
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored);
|
||||
static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
|
||||
@@ -2067,13 +2067,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int acpi_video_bus_remove(struct acpi_device *device)
|
||||
static void acpi_video_bus_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_video_bus *video = NULL;
|
||||
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
video = acpi_driver_data(device);
|
||||
|
||||
@@ -2087,8 +2087,6 @@ static int acpi_video_bus_remove(struct acpi_device *device)
|
||||
|
||||
kfree(video->attached_array);
|
||||
kfree(video);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)
|
||||
|
||||
@@ -155,6 +155,7 @@ acpi-y += \
|
||||
utalloc.o \
|
||||
utascii.o \
|
||||
utbuffer.o \
|
||||
utcksum.o \
|
||||
utcopy.o \
|
||||
utexcep.o \
|
||||
utdebug.o \
|
||||
|
||||
@@ -24,6 +24,7 @@ ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list);
|
||||
|
||||
ACPI_GLOBAL(struct acpi_table_header *, acpi_gbl_DSDT);
|
||||
ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header);
|
||||
ACPI_INIT_GLOBAL(char *, acpi_gbl_CDAT, NULL);
|
||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
|
||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
|
||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
|
||||
|
||||
@@ -124,11 +124,6 @@ void
|
||||
acpi_tb_print_table_header(acpi_physical_address address,
|
||||
struct acpi_table_header *header);
|
||||
|
||||
u8 acpi_tb_checksum(u8 *buffer, u32 length);
|
||||
|
||||
acpi_status
|
||||
acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
|
||||
|
||||
void acpi_tb_check_dsdt_header(void);
|
||||
|
||||
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);
|
||||
|
||||
@@ -158,6 +158,19 @@ u8 acpi_ut_valid_name_char(char character, u32 position);
|
||||
|
||||
void acpi_ut_check_and_repair_ascii(u8 *name, char *repaired_name, u32 count);
|
||||
|
||||
/*
|
||||
* utcksum - Checksum utilities
|
||||
*/
|
||||
u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum);
|
||||
|
||||
u8 acpi_ut_checksum(u8 *buffer, u32 length);
|
||||
|
||||
acpi_status
|
||||
acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length);
|
||||
|
||||
acpi_status
|
||||
acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length);
|
||||
|
||||
/*
|
||||
* utnonansi - Non-ANSI C library functions
|
||||
*/
|
||||
|
||||
@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
|
||||
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
|
||||
if (!info) {
|
||||
status = AE_NO_MEMORY;
|
||||
goto cleanup;
|
||||
goto pop_walk_state;
|
||||
}
|
||||
|
||||
info->parameters = &this_walk_state->operands[0];
|
||||
@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
|
||||
|
||||
ACPI_FREE(info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
goto pop_walk_state;
|
||||
}
|
||||
|
||||
next_walk_state->method_nesting_depth =
|
||||
@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
pop_walk_state:
|
||||
|
||||
/* On error, pop the walk state to be deleted from thread */
|
||||
|
||||
acpi_ds_pop_walk_state(thread);
|
||||
|
||||
cleanup:
|
||||
|
||||
/* On error, we must terminate the method properly */
|
||||
|
||||
@@ -142,6 +142,9 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
|
||||
status =
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[i].enable_register_id,
|
||||
(i ==
|
||||
ACPI_EVENT_PCIE_WAKE) ?
|
||||
ACPI_ENABLE_EVENT :
|
||||
ACPI_DISABLE_EVENT);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
@@ -185,6 +188,11 @@ u32 acpi_ev_fixed_event_detect(void)
|
||||
return (int_status);
|
||||
}
|
||||
|
||||
if (fixed_enable & ACPI_BITMASK_PCIEXP_WAKE_DISABLE)
|
||||
fixed_enable &= ~ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
|
||||
else
|
||||
fixed_enable |= ACPI_BITMASK_PCIEXP_WAKE_DISABLE;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
|
||||
"Fixed Event Block: Enable %08X Status %08X\n",
|
||||
fixed_enable, fixed_status));
|
||||
@@ -250,6 +258,9 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
|
||||
if (!acpi_gbl_fixed_event_handlers[event].handler) {
|
||||
(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
|
||||
enable_register_id,
|
||||
(event ==
|
||||
ACPI_EVENT_PCIE_WAKE) ?
|
||||
ACPI_ENABLE_EVENT :
|
||||
ACPI_DISABLE_EVENT);
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
|
||||
@@ -172,6 +172,15 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
|
||||
ctx->subspace_id = (u8)region_obj->region.address;
|
||||
}
|
||||
|
||||
if (region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_FIXED_HARDWARE) {
|
||||
struct acpi_ffh_info *ctx =
|
||||
handler_desc->address_space.context;
|
||||
|
||||
ctx->length = region_obj->region.length;
|
||||
ctx->offset = region_obj->region.address;
|
||||
}
|
||||
|
||||
/*
|
||||
* We must exit the interpreter because the region setup will
|
||||
* potentially execute control methods (for example, the _REG method
|
||||
|
||||
@@ -295,8 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
|
||||
target));
|
||||
}
|
||||
if (target->common.type != ACPI_TYPE_INTEGER) {
|
||||
ACPI_EXCEPTION((AE_INFO, AE_TYPE,
|
||||
"Type not integer: %X\n", target->common.type));
|
||||
ACPI_ERROR((AE_INFO, "Type not integer: %X",
|
||||
target->common.type));
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,9 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_IPMI
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_PLATFORM_RT)) {
|
||||
ACPI_ADR_SPACE_PLATFORM_RT
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
|
||||
|
||||
/* SMBus, GSBus, IPMI serial */
|
||||
|
||||
@@ -305,7 +307,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_IPMI
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_PLATFORM_RT)) {
|
||||
ACPI_ADR_SPACE_PLATFORM_RT
|
||||
|| obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_FIXED_HARDWARE)) {
|
||||
|
||||
/* SMBus, GSBus, IPMI serial */
|
||||
|
||||
|
||||
@@ -323,6 +323,12 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
|
||||
function = ACPI_WRITE;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_FIXED_HARDWARE:
|
||||
|
||||
buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
|
||||
function = ACPI_WRITE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
|
||||
}
|
||||
|
||||
@@ -311,6 +311,20 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
|
||||
[ACPI_EVENT_SLEEP_BUTTON].
|
||||
status_register_id, ACPI_CLEAR_STATUS);
|
||||
|
||||
/* Enable pcie wake event if support */
|
||||
if ((acpi_gbl_FADT.flags & ACPI_FADT_PCI_EXPRESS_WAKE)) {
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_PCIE_WAKE].
|
||||
enable_register_id,
|
||||
ACPI_DISABLE_EVENT);
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_PCIE_WAKE].
|
||||
status_register_id,
|
||||
ACPI_CLEAR_STATUS);
|
||||
}
|
||||
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
@@ -522,7 +522,7 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
|
||||
/* Verify the checksum */
|
||||
|
||||
status =
|
||||
acpi_tb_verify_checksum(table_desc->pointer,
|
||||
acpi_ut_verify_checksum(table_desc->pointer,
|
||||
table_desc->length);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
|
||||
|
||||
@@ -298,7 +298,7 @@ void acpi_tb_parse_fadt(void)
|
||||
* Validate the FADT checksum before we copy the table. Ignore
|
||||
* checksum error as we want to try to get the DSDT and FACS.
|
||||
*/
|
||||
(void)acpi_tb_verify_checksum(table, length);
|
||||
(void)acpi_ut_verify_checksum(table, length);
|
||||
|
||||
/* Create a local copy of the FADT in common ACPI 2.0+ format */
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "actables.h"
|
||||
#include "acutils.h"
|
||||
|
||||
#define _COMPONENT ACPI_TABLES
|
||||
ACPI_MODULE_NAME("tbprint")
|
||||
@@ -39,7 +40,7 @@ static void acpi_tb_fix_string(char *string, acpi_size length)
|
||||
{
|
||||
|
||||
while (length && *string) {
|
||||
if (!isprint((int)*string)) {
|
||||
if (!isprint((int)(u8)*string)) {
|
||||
*string = '?';
|
||||
}
|
||||
|
||||
@@ -135,77 +136,3 @@ acpi_tb_print_table_header(acpi_physical_address address,
|
||||
local_header.asl_compiler_revision));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_validate_checksum
|
||||
*
|
||||
* PARAMETERS: table - ACPI table to verify
|
||||
* length - Length of entire table
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
|
||||
* exception on bad checksum.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
|
||||
{
|
||||
u8 checksum;
|
||||
|
||||
/*
|
||||
* FACS/S3PT:
|
||||
* They are the odd tables, have no standard ACPI header and no checksum
|
||||
*/
|
||||
|
||||
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
|
||||
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* Compute the checksum on the table */
|
||||
|
||||
checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
|
||||
|
||||
/* Checksum ok? (should be zero) */
|
||||
|
||||
if (checksum) {
|
||||
ACPI_BIOS_WARNING((AE_INFO,
|
||||
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
|
||||
"should be 0x%2.2X",
|
||||
table->signature, table->checksum,
|
||||
(u8)(table->checksum - checksum)));
|
||||
|
||||
#if (ACPI_CHECKSUM_ABORT)
|
||||
return (AE_BAD_CHECKSUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_checksum
|
||||
*
|
||||
* PARAMETERS: buffer - Pointer to memory region to be checked
|
||||
* length - Length of this memory region
|
||||
*
|
||||
* RETURN: Checksum (u8)
|
||||
*
|
||||
* DESCRIPTION: Calculates circular checksum of memory region.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
u8 acpi_tb_checksum(u8 *buffer, u32 length)
|
||||
{
|
||||
u8 sum = 0;
|
||||
u8 *end = buffer + length;
|
||||
|
||||
while (buffer < end) {
|
||||
sum = (u8)(sum + *(buffer++));
|
||||
}
|
||||
|
||||
return (sum);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
|
||||
|
||||
/* Validate the root table checksum */
|
||||
|
||||
status = acpi_tb_verify_checksum(table, length);
|
||||
status = acpi_ut_verify_checksum(table, length);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_os_unmap_memory(table, length);
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
@@ -74,14 +74,14 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
|
||||
|
||||
/* Check the standard checksum */
|
||||
|
||||
if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
|
||||
if (acpi_ut_checksum((u8 *)rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
|
||||
return (AE_BAD_CHECKSUM);
|
||||
}
|
||||
|
||||
/* Check extended checksum if table version >= 2 */
|
||||
|
||||
if ((rsdp->revision >= 2) &&
|
||||
(acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
|
||||
(acpi_ut_checksum((u8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
|
||||
return (AE_BAD_CHECKSUM);
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
|
||||
u8 *table_ptr;
|
||||
u8 *mem_rover;
|
||||
u32 physical_address;
|
||||
u32 ebda_window_size;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
|
||||
|
||||
@@ -139,26 +140,37 @@ acpi_find_root_pointer(acpi_physical_address *table_address)
|
||||
|
||||
/* EBDA present? */
|
||||
|
||||
if (physical_address > 0x400) {
|
||||
/*
|
||||
* Check that the EBDA pointer from memory is sane and does not point
|
||||
* above valid low memory
|
||||
*/
|
||||
if (physical_address > 0x400 && physical_address < 0xA0000) {
|
||||
/*
|
||||
* 1b) Search EBDA paragraphs (EBDA is required to be a
|
||||
* minimum of 1K length)
|
||||
* Calculate the scan window size
|
||||
* The EBDA is not guaranteed to be larger than a ki_b and in case
|
||||
* that it is smaller, the scanning function would leave the low
|
||||
* memory and continue to the VGA range.
|
||||
*/
|
||||
ebda_window_size = ACPI_MIN(ACPI_EBDA_WINDOW_SIZE,
|
||||
0xA0000 - physical_address);
|
||||
|
||||
/*
|
||||
* 1b) Search EBDA paragraphs
|
||||
*/
|
||||
table_ptr = acpi_os_map_memory((acpi_physical_address)
|
||||
physical_address,
|
||||
ACPI_EBDA_WINDOW_SIZE);
|
||||
ebda_window_size);
|
||||
if (!table_ptr) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Could not map memory at 0x%8.8X for length %u",
|
||||
physical_address, ACPI_EBDA_WINDOW_SIZE));
|
||||
physical_address, ebda_window_size));
|
||||
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
mem_rover =
|
||||
acpi_tb_scan_memory_for_rsdp(table_ptr,
|
||||
ACPI_EBDA_WINDOW_SIZE);
|
||||
acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
|
||||
acpi_tb_scan_memory_for_rsdp(table_ptr, ebda_window_size);
|
||||
acpi_os_unmap_memory(table_ptr, ebda_window_size);
|
||||
|
||||
if (mem_rover) {
|
||||
|
||||
|
||||
170
drivers/acpi/acpica/utcksum.c
Normal file
170
drivers/acpi/acpica/utcksum.c
Normal file
@@ -0,0 +1,170 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: utcksum - Support generating table checksums
|
||||
*
|
||||
* Copyright (C) 2000 - 2022, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "acutils.h"
|
||||
|
||||
/* This module used for application-level code only */
|
||||
|
||||
#define _COMPONENT ACPI_CA_DISASSEMBLER
|
||||
ACPI_MODULE_NAME("utcksum")
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_verify_checksum
|
||||
*
|
||||
* PARAMETERS: table - ACPI table to verify
|
||||
* length - Length of entire table
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
|
||||
* exception on bad checksum.
|
||||
* Note: We don't have to check for a CDAT here, since CDAT is
|
||||
* not in the RSDT/XSDT, and the CDAT table is never installed
|
||||
* via ACPICA.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_ut_verify_checksum(struct acpi_table_header *table, u32 length)
|
||||
{
|
||||
u8 checksum;
|
||||
|
||||
/*
|
||||
* FACS/S3PT:
|
||||
* They are the odd tables, have no standard ACPI header and no checksum
|
||||
*/
|
||||
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
|
||||
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* Compute the checksum on the table */
|
||||
|
||||
length = table->length;
|
||||
checksum =
|
||||
acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, table), length,
|
||||
table->checksum);
|
||||
|
||||
/* Computed checksum matches table? */
|
||||
|
||||
if (checksum != table->checksum) {
|
||||
ACPI_BIOS_WARNING((AE_INFO,
|
||||
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
|
||||
"should be 0x%2.2X",
|
||||
table->signature, table->checksum,
|
||||
table->checksum - checksum));
|
||||
|
||||
#if (ACPI_CHECKSUM_ABORT)
|
||||
return (AE_BAD_CHECKSUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_verify_cdat_checksum
|
||||
*
|
||||
* PARAMETERS: table - CDAT ACPI table to verify
|
||||
* length - Length of entire table
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Verifies that the CDAT table checksums to zero. Optionally
|
||||
* returns an exception on bad checksum.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ut_verify_cdat_checksum(struct acpi_table_cdat *cdat_table, u32 length)
|
||||
{
|
||||
u8 checksum;
|
||||
|
||||
/* Compute the checksum on the table */
|
||||
|
||||
checksum = acpi_ut_generate_checksum(ACPI_CAST_PTR(u8, cdat_table),
|
||||
cdat_table->length,
|
||||
cdat_table->checksum);
|
||||
|
||||
/* Computed checksum matches table? */
|
||||
|
||||
if (checksum != cdat_table->checksum) {
|
||||
ACPI_BIOS_WARNING((AE_INFO,
|
||||
"Incorrect checksum in table [%4.4s] - 0x%2.2X, "
|
||||
"should be 0x%2.2X",
|
||||
acpi_gbl_CDAT, cdat_table->checksum,
|
||||
checksum));
|
||||
|
||||
#if (ACPI_CHECKSUM_ABORT)
|
||||
return (AE_BAD_CHECKSUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
cdat_table->checksum = checksum;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_generate_checksum
|
||||
*
|
||||
* PARAMETERS: table - Pointer to table to be checksummed
|
||||
* length - Length of the table
|
||||
* original_checksum - Value of the checksum field
|
||||
*
|
||||
* RETURN: 8 bit checksum of buffer
|
||||
*
|
||||
* DESCRIPTION: Computes an 8 bit checksum of the table.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
u8 acpi_ut_generate_checksum(void *table, u32 length, u8 original_checksum)
|
||||
{
|
||||
u8 checksum;
|
||||
|
||||
/* Sum the entire table as-is */
|
||||
|
||||
checksum = acpi_ut_checksum((u8 *)table, length);
|
||||
|
||||
/* Subtract off the existing checksum value in the table */
|
||||
|
||||
checksum = (u8)(checksum - original_checksum);
|
||||
|
||||
/* Compute and return the final checksum */
|
||||
|
||||
checksum = (u8)(0 - checksum);
|
||||
return (checksum);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ut_checksum
|
||||
*
|
||||
* PARAMETERS: buffer - Pointer to memory region to be checked
|
||||
* length - Length of this memory region
|
||||
*
|
||||
* RETURN: Checksum (u8)
|
||||
*
|
||||
* DESCRIPTION: Calculates circular checksum of memory region.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
u8 acpi_ut_checksum(u8 *buffer, u32 length)
|
||||
{
|
||||
u8 sum = 0;
|
||||
u8 *end = buffer + length;
|
||||
|
||||
while (buffer < end) {
|
||||
sum = (u8)(sum + *(buffer++));
|
||||
}
|
||||
|
||||
return (sum);
|
||||
}
|
||||
@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
|
||||
status = acpi_ut_walk_package_tree(source_obj, dest_obj,
|
||||
acpi_ut_copy_ielement_to_ielement,
|
||||
walk_state);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
|
||||
/* On failure, delete the destination package object */
|
||||
|
||||
acpi_ut_remove_reference(dest_obj);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,6 +186,10 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
|
||||
ACPI_BITREG_RT_CLOCK_ENABLE,
|
||||
ACPI_BITMASK_RT_CLOCK_STATUS,
|
||||
ACPI_BITMASK_RT_CLOCK_ENABLE},
|
||||
/* ACPI_EVENT_PCIE_WAKE */ {ACPI_BITREG_PCIEXP_WAKE_STATUS,
|
||||
ACPI_BITREG_PCIEXP_WAKE_DISABLE,
|
||||
ACPI_BITMASK_PCIEXP_WAKE_STATUS,
|
||||
ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
|
||||
};
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ void acpi_ut_repair_name(char *name)
|
||||
return;
|
||||
}
|
||||
|
||||
ACPI_COPY_NAMESEG(&original_name, name);
|
||||
ACPI_COPY_NAMESEG(&original_name, &name[0]);
|
||||
|
||||
/* Check each character in the name */
|
||||
|
||||
@@ -156,10 +156,10 @@ void acpi_ut_repair_name(char *name)
|
||||
|
||||
/*
|
||||
* Replace a bad character with something printable, yet technically
|
||||
* still invalid. This prevents any collisions with existing "good"
|
||||
* "odd". This prevents any collisions with existing "good"
|
||||
* names in the namespace.
|
||||
*/
|
||||
name[i] = '*';
|
||||
name[i] = '_';
|
||||
found_bad_char = TRUE;
|
||||
}
|
||||
|
||||
@@ -169,8 +169,8 @@ void acpi_ut_repair_name(char *name)
|
||||
|
||||
if (!acpi_gbl_enable_interpreter_slack) {
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
||||
original_name, name));
|
||||
"Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]",
|
||||
original_name, name, &name[0]));
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <acpi/apei.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "apei-internal.h"
|
||||
|
||||
@@ -358,6 +358,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
|
||||
*/
|
||||
if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
|
||||
struct apei_resources addr_resources;
|
||||
|
||||
apei_resources_init(&addr_resources);
|
||||
trigger_param_region = einj_get_trigger_parameter_region(
|
||||
trigger_tab, param1, param2);
|
||||
@@ -432,11 +433,11 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
||||
}
|
||||
v5param->flags = vendor_flags;
|
||||
} else if (flags) {
|
||||
v5param->flags = flags;
|
||||
v5param->memory_address = param1;
|
||||
v5param->memory_address_range = param2;
|
||||
v5param->apicid = param3;
|
||||
v5param->pcie_sbdf = param4;
|
||||
v5param->flags = flags;
|
||||
v5param->memory_address = param1;
|
||||
v5param->memory_address_range = param2;
|
||||
v5param->apicid = param3;
|
||||
v5param->pcie_sbdf = param4;
|
||||
} else {
|
||||
switch (type) {
|
||||
case ACPI_EINJ_PROCESSOR_CORRECTABLE:
|
||||
@@ -466,6 +467,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
||||
return rc;
|
||||
if (einj_param) {
|
||||
struct einj_parameter *v4param = einj_param;
|
||||
|
||||
v4param->param1 = param1;
|
||||
v4param->param2 = param2;
|
||||
}
|
||||
@@ -569,6 +571,20 @@ static u64 error_param2;
|
||||
static u64 error_param3;
|
||||
static u64 error_param4;
|
||||
static struct dentry *einj_debug_dir;
|
||||
static const char * const einj_error_type_string[] = {
|
||||
"0x00000001\tProcessor Correctable\n",
|
||||
"0x00000002\tProcessor Uncorrectable non-fatal\n",
|
||||
"0x00000004\tProcessor Uncorrectable fatal\n",
|
||||
"0x00000008\tMemory Correctable\n",
|
||||
"0x00000010\tMemory Uncorrectable non-fatal\n",
|
||||
"0x00000020\tMemory Uncorrectable fatal\n",
|
||||
"0x00000040\tPCI Express Correctable\n",
|
||||
"0x00000080\tPCI Express Uncorrectable non-fatal\n",
|
||||
"0x00000100\tPCI Express Uncorrectable fatal\n",
|
||||
"0x00000200\tPlatform Correctable\n",
|
||||
"0x00000400\tPlatform Uncorrectable non-fatal\n",
|
||||
"0x00000800\tPlatform Uncorrectable fatal\n",
|
||||
};
|
||||
|
||||
static int available_error_type_show(struct seq_file *m, void *v)
|
||||
{
|
||||
@@ -578,30 +594,9 @@ static int available_error_type_show(struct seq_file *m, void *v)
|
||||
rc = einj_get_available_error_type(&available_error_type);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (available_error_type & 0x0001)
|
||||
seq_printf(m, "0x00000001\tProcessor Correctable\n");
|
||||
if (available_error_type & 0x0002)
|
||||
seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n");
|
||||
if (available_error_type & 0x0004)
|
||||
seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n");
|
||||
if (available_error_type & 0x0008)
|
||||
seq_printf(m, "0x00000008\tMemory Correctable\n");
|
||||
if (available_error_type & 0x0010)
|
||||
seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n");
|
||||
if (available_error_type & 0x0020)
|
||||
seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n");
|
||||
if (available_error_type & 0x0040)
|
||||
seq_printf(m, "0x00000040\tPCI Express Correctable\n");
|
||||
if (available_error_type & 0x0080)
|
||||
seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n");
|
||||
if (available_error_type & 0x0100)
|
||||
seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n");
|
||||
if (available_error_type & 0x0200)
|
||||
seq_printf(m, "0x00000200\tPlatform Correctable\n");
|
||||
if (available_error_type & 0x0400)
|
||||
seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n");
|
||||
if (available_error_type & 0x0800)
|
||||
seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n");
|
||||
for (int pos = 0; pos < ARRAY_SIZE(einj_error_type_string); pos++)
|
||||
if (available_error_type & BIT(pos))
|
||||
seq_puts(m, einj_error_type_string[pos]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -689,8 +684,7 @@ static int __init einj_init(void)
|
||||
if (status == AE_NOT_FOUND) {
|
||||
pr_warn("EINJ table not found.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
else if (ACPI_FAILURE(status)) {
|
||||
} else if (ACPI_FAILURE(status)) {
|
||||
pr_err("Failed to get EINJ table: %s\n",
|
||||
acpi_format_exception(status));
|
||||
return -EINVAL;
|
||||
|
||||
@@ -138,7 +138,7 @@ struct ghes_vendor_record_entry {
|
||||
static struct gen_pool *ghes_estatus_pool;
|
||||
static unsigned long ghes_estatus_pool_size_request;
|
||||
|
||||
static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
|
||||
static struct ghes_estatus_cache __rcu *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
|
||||
static atomic_t ghes_estatus_cache_alloced;
|
||||
|
||||
static int ghes_panic_timeout __read_mostly = 30;
|
||||
@@ -773,48 +773,42 @@ static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
|
||||
return cache;
|
||||
}
|
||||
|
||||
static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache)
|
||||
static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
|
||||
{
|
||||
struct ghes_estatus_cache *cache;
|
||||
u32 len;
|
||||
|
||||
cache = container_of(head, struct ghes_estatus_cache, rcu);
|
||||
len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache));
|
||||
len = GHES_ESTATUS_CACHE_LEN(len);
|
||||
gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len);
|
||||
atomic_dec(&ghes_estatus_cache_alloced);
|
||||
}
|
||||
|
||||
static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
|
||||
static void
|
||||
ghes_estatus_cache_add(struct acpi_hest_generic *generic,
|
||||
struct acpi_hest_generic_status *estatus)
|
||||
{
|
||||
struct ghes_estatus_cache *cache;
|
||||
|
||||
cache = container_of(head, struct ghes_estatus_cache, rcu);
|
||||
ghes_estatus_cache_free(cache);
|
||||
}
|
||||
|
||||
static void ghes_estatus_cache_add(
|
||||
struct acpi_hest_generic *generic,
|
||||
struct acpi_hest_generic_status *estatus)
|
||||
{
|
||||
int i, slot = -1, count;
|
||||
unsigned long long now, duration, period, max_period = 0;
|
||||
struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache;
|
||||
struct ghes_estatus_cache *cache, *new_cache;
|
||||
struct ghes_estatus_cache __rcu *victim;
|
||||
int i, slot = -1, count;
|
||||
|
||||
new_cache = ghes_estatus_cache_alloc(generic, estatus);
|
||||
if (new_cache == NULL)
|
||||
if (!new_cache)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
now = sched_clock();
|
||||
for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
|
||||
cache = rcu_dereference(ghes_estatus_caches[i]);
|
||||
if (cache == NULL) {
|
||||
slot = i;
|
||||
slot_cache = NULL;
|
||||
break;
|
||||
}
|
||||
duration = now - cache->time_in;
|
||||
if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) {
|
||||
slot = i;
|
||||
slot_cache = cache;
|
||||
break;
|
||||
}
|
||||
count = atomic_read(&cache->count);
|
||||
@@ -823,18 +817,30 @@ static void ghes_estatus_cache_add(
|
||||
if (period > max_period) {
|
||||
max_period = period;
|
||||
slot = i;
|
||||
slot_cache = cache;
|
||||
}
|
||||
}
|
||||
/* new_cache must be put into array after its contents are written */
|
||||
smp_wmb();
|
||||
if (slot != -1 && cmpxchg(ghes_estatus_caches + slot,
|
||||
slot_cache, new_cache) == slot_cache) {
|
||||
if (slot_cache)
|
||||
call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free);
|
||||
} else
|
||||
ghes_estatus_cache_free(new_cache);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (slot != -1) {
|
||||
/*
|
||||
* Use release semantics to ensure that ghes_estatus_cached()
|
||||
* running on another CPU will see the updated cache fields if
|
||||
* it can see the new value of the pointer.
|
||||
*/
|
||||
victim = xchg_release(&ghes_estatus_caches[slot],
|
||||
RCU_INITIALIZER(new_cache));
|
||||
|
||||
/*
|
||||
* At this point, victim may point to a cached item different
|
||||
* from the one based on which we selected the slot. Instead of
|
||||
* going to the loop again to pick another slot, let's just
|
||||
* drop the other item anyway: this may cause a false cache
|
||||
* miss later on, but that won't cause any problems.
|
||||
*/
|
||||
if (victim)
|
||||
call_rcu(&unrcu_pointer(victim)->rcu,
|
||||
ghes_estatus_cache_rcu_free);
|
||||
}
|
||||
}
|
||||
|
||||
static void __ghes_panic(struct ghes *ghes,
|
||||
@@ -1444,8 +1450,6 @@ static int ghes_remove(struct platform_device *ghes_dev)
|
||||
|
||||
kfree(ghes);
|
||||
|
||||
platform_set_drvdata(ghes_dev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -696,7 +696,8 @@ static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
|
||||
if (lock)
|
||||
mutex_lock(&hook_mutex);
|
||||
list_for_each_entry(battery, &acpi_battery_list, list) {
|
||||
hook->remove_battery(battery->bat);
|
||||
if (!hook->remove_battery(battery->bat))
|
||||
power_supply_changed(battery->bat);
|
||||
}
|
||||
list_del(&hook->list);
|
||||
if (lock)
|
||||
@@ -735,6 +736,8 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
||||
__battery_hook_unregister(hook, 0);
|
||||
goto end;
|
||||
}
|
||||
|
||||
power_supply_changed(battery->bat);
|
||||
}
|
||||
pr_info("new extension: %s\n", hook->name);
|
||||
end:
|
||||
@@ -1208,12 +1211,12 @@ static int acpi_battery_add(struct acpi_device *device)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_battery_remove(struct acpi_device *device)
|
||||
static void acpi_battery_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_battery *battery = NULL;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
device_init_wakeup(&device->dev, 0);
|
||||
battery = acpi_driver_data(device);
|
||||
unregister_pm_notifier(&battery->pm_nb);
|
||||
@@ -1221,7 +1224,6 @@ static int acpi_battery_remove(struct acpi_device *device)
|
||||
mutex_destroy(&battery->lock);
|
||||
mutex_destroy(&battery->sysfs_lock);
|
||||
kfree(battery);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -323,6 +323,8 @@ static void acpi_bus_osc_negotiate_platform_control(void)
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
|
||||
if (IS_ENABLED(CONFIG_ACPI_PRMT))
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
|
||||
if (IS_ENABLED(CONFIG_ACPI_FFH))
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FFH_OPR_SUPPORT;
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
|
||||
@@ -1408,6 +1410,7 @@ static int __init acpi_init(void)
|
||||
disable_acpi();
|
||||
return result;
|
||||
}
|
||||
acpi_init_ffh();
|
||||
|
||||
pci_mmcfg_late_init();
|
||||
acpi_iort_init();
|
||||
|
||||
@@ -125,7 +125,7 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
|
||||
};
|
||||
|
||||
static int acpi_button_add(struct acpi_device *device);
|
||||
static int acpi_button_remove(struct acpi_device *device);
|
||||
static void acpi_button_remove(struct acpi_device *device);
|
||||
static void acpi_button_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -580,14 +580,13 @@ static int acpi_button_add(struct acpi_device *device)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int acpi_button_remove(struct acpi_device *device)
|
||||
static void acpi_button_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
|
||||
acpi_button_remove_fs(device);
|
||||
input_unregister_device(button->input);
|
||||
kfree(button);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int param_set_lid_init_state(const char *val,
|
||||
|
||||
@@ -148,7 +148,7 @@ __ATTR(_name, 0444, show_##_name, NULL)
|
||||
if (ret) \
|
||||
return ret; \
|
||||
\
|
||||
return scnprintf(buf, PAGE_SIZE, "%llu\n", \
|
||||
return sysfs_emit(buf, "%llu\n", \
|
||||
(u64)st_name.member_name); \
|
||||
} \
|
||||
define_one_cppc_ro(member_name)
|
||||
@@ -174,7 +174,7 @@ static ssize_t show_feedback_ctrs(struct kobject *kobj,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "ref:%llu del:%llu\n",
|
||||
return sysfs_emit(buf, "ref:%llu del:%llu\n",
|
||||
fb_ctrs.reference, fb_ctrs.delivered);
|
||||
}
|
||||
define_one_cppc_ro(feedback_ctrs);
|
||||
|
||||
@@ -1663,12 +1663,12 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int acpi_ec_remove(struct acpi_device *device)
|
||||
static void acpi_ec_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_ec *ec;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
ec = acpi_driver_data(device);
|
||||
release_region(ec->data_addr, 1);
|
||||
@@ -1678,7 +1678,6 @@ static int acpi_ec_remove(struct acpi_device *device)
|
||||
ec_remove_handlers(ec);
|
||||
acpi_ec_free(ec);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
@@ -1875,6 +1874,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* HP Pavilion Gaming Laptop 15-cx0041ur
|
||||
*/
|
||||
.callback = ec_honor_dsdt_gpe,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Samsung hardware
|
||||
|
||||
@@ -27,24 +27,24 @@ static ssize_t show_state(struct device *dev, struct device_attribute *attr, cha
|
||||
count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
|
||||
|
||||
if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
count += sysfs_emit_at(buf, count, "not-defined:");
|
||||
else
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
|
||||
count += sysfs_emit_at(buf, count, "%lld:", fps->trip_point);
|
||||
|
||||
if (fps->speed == 0xFFFFFFFF)
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
count += sysfs_emit_at(buf, count, "not-defined:");
|
||||
else
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
|
||||
count += sysfs_emit_at(buf, count, "%lld:", fps->speed);
|
||||
|
||||
if (fps->noise_level == 0xFFFFFFFF)
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
count += sysfs_emit_at(buf, count, "not-defined:");
|
||||
else
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
|
||||
count += sysfs_emit_at(buf, count, "%lld:", fps->noise_level * 100);
|
||||
|
||||
if (fps->power == 0xFFFFFFFF)
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
|
||||
count += sysfs_emit_at(buf, count, "not-defined\n");
|
||||
else
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
|
||||
count += sysfs_emit_at(buf, count, "%lld\n", fps->power);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -236,6 +236,7 @@ static int acpi_fan_get_fif(struct acpi_device *device)
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev, "Invalid _FIF element\n");
|
||||
status = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
fan->fif.revision = fields[0];
|
||||
|
||||
@@ -56,10 +56,9 @@ static int acpi_hed_add(struct acpi_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_hed_remove(struct acpi_device *device)
|
||||
static void acpi_hed_remove(struct acpi_device *device)
|
||||
{
|
||||
hed_handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct acpi_driver acpi_hed_driver = {
|
||||
|
||||
@@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
|
||||
/**
|
||||
* acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source.
|
||||
* @source: acpi_resource_source to use for the lookup.
|
||||
* @gsi: GSI IRQ number
|
||||
*
|
||||
* Description:
|
||||
* Retrieve the fwhandle of the device referenced by the given IRQ resource
|
||||
@@ -297,8 +298,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get);
|
||||
/**
|
||||
* acpi_set_irq_model - Setup the GSI irqdomain information
|
||||
* @model: the value assigned to acpi_irq_model
|
||||
* @fwnode: the irq_domain identifier for mapping and looking up
|
||||
* GSI interrupts
|
||||
* @fn: a dispatcher function that will return the domain fwnode
|
||||
* for a given GSI
|
||||
*/
|
||||
void __init acpi_set_irq_model(enum acpi_irq_model_id model,
|
||||
struct fwnode_handle *(*fn)(u32))
|
||||
|
||||
@@ -3371,10 +3371,9 @@ static int acpi_nfit_add(struct acpi_device *adev)
|
||||
return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
|
||||
}
|
||||
|
||||
static int acpi_nfit_remove(struct acpi_device *adev)
|
||||
static void acpi_nfit_remove(struct acpi_device *adev)
|
||||
{
|
||||
/* see acpi_nfit_unregister */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
|
||||
|
||||
@@ -387,13 +387,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
||||
u8 pin;
|
||||
int triggering = ACPI_LEVEL_SENSITIVE;
|
||||
/*
|
||||
* On ARM systems with the GIC interrupt model, level interrupts
|
||||
* On ARM systems with the GIC interrupt model, or LoongArch
|
||||
* systems with the LPIC interrupt model, level interrupts
|
||||
* are always polarity high by specification; PCI legacy
|
||||
* IRQs lines are inverted before reaching the interrupt
|
||||
* controller and must therefore be considered active high
|
||||
* as default.
|
||||
*/
|
||||
int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ?
|
||||
int polarity = acpi_irq_model == ACPI_IRQ_MODEL_GIC ||
|
||||
acpi_irq_model == ACPI_IRQ_MODEL_LPIC ?
|
||||
ACPI_ACTIVE_HIGH : ACPI_ACTIVE_LOW;
|
||||
char *link = NULL;
|
||||
char link_desc[16];
|
||||
|
||||
@@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info,
|
||||
ret = 0;
|
||||
|
||||
free_acpi_buffer:
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev)
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev)
|
||||
ret = obj->integer.value;
|
||||
|
||||
free_acpi_buffer:
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr,
|
||||
ret = 0;
|
||||
|
||||
free_acpi_buffer:
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info,
|
||||
ret = 0;
|
||||
|
||||
free_acpi_buffer:
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev)
|
||||
ret = 0;
|
||||
|
||||
free_acpi_buffer:
|
||||
kfree(out_obj);
|
||||
ACPI_FREE(out_obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -967,7 +967,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
|
||||
if (acpi_power_get_state(resource, &state_dummy))
|
||||
__acpi_power_on(resource);
|
||||
|
||||
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
|
||||
acpi_handle_info(handle, "New power resource\n");
|
||||
|
||||
result = acpi_tie_acpi_dev(device);
|
||||
if (result)
|
||||
|
||||
@@ -324,7 +324,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
||||
* the erratum), but this is known to disrupt certain ISA
|
||||
* devices thus we take the conservative approach.
|
||||
*/
|
||||
else if (errata.piix4.fdma) {
|
||||
if (errata.piix4.fdma) {
|
||||
acpi_handle_debug(pr->handle,
|
||||
"C3 not supported on PIIX4 with Type-F DMA\n");
|
||||
return;
|
||||
@@ -384,8 +384,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
||||
* handle BM_RLD is to set it and leave it set.
|
||||
*/
|
||||
acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int acpi_cst_latency_cmp(const void *a, const void *b)
|
||||
@@ -459,7 +457,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
|
||||
|
||||
lapic_timer_propagate_broadcast(pr);
|
||||
|
||||
return (working);
|
||||
return working;
|
||||
}
|
||||
|
||||
static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
|
||||
@@ -1134,6 +1132,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
|
||||
status = acpi_get_parent(handle, &pr_ahandle);
|
||||
while (ACPI_SUCCESS(status)) {
|
||||
d = acpi_fetch_acpi_dev(pr_ahandle);
|
||||
if (!d)
|
||||
break;
|
||||
|
||||
handle = pr_ahandle;
|
||||
|
||||
if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID))
|
||||
|
||||
@@ -142,6 +142,7 @@ int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
|
||||
pr = per_cpu(processors, cpu);
|
||||
if (!pr || !pr->performance || !pr->performance->state_count)
|
||||
return -ENODEV;
|
||||
|
||||
*limit = pr->performance->states[pr->performance_platform_limit].
|
||||
core_frequency * 1000;
|
||||
return 0;
|
||||
@@ -201,8 +202,7 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
pct = (union acpi_object *)buffer.pointer;
|
||||
if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
|
||||
|| (pct->package.count != 2)) {
|
||||
if (!pct || pct->type != ACPI_TYPE_PACKAGE || pct->package.count != 2) {
|
||||
pr_err("Invalid _PCT data\n");
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
@@ -214,9 +214,8 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
|
||||
obj = pct->package.elements[0];
|
||||
|
||||
if ((obj.type != ACPI_TYPE_BUFFER)
|
||||
|| (obj.buffer.length < sizeof(struct acpi_pct_register))
|
||||
|| (obj.buffer.pointer == NULL)) {
|
||||
if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER ||
|
||||
obj.buffer.length < sizeof(struct acpi_pct_register)) {
|
||||
pr_err("Invalid _PCT data (control_register)\n");
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
@@ -230,9 +229,8 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
|
||||
obj = pct->package.elements[1];
|
||||
|
||||
if ((obj.type != ACPI_TYPE_BUFFER)
|
||||
|| (obj.buffer.length < sizeof(struct acpi_pct_register))
|
||||
|| (obj.buffer.pointer == NULL)) {
|
||||
if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER ||
|
||||
obj.buffer.length < sizeof(struct acpi_pct_register)) {
|
||||
pr_err("Invalid _PCT data (status_register)\n");
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
@@ -260,8 +258,8 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
|
||||
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
|
||||
return;
|
||||
|
||||
if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
|
||||
|| boot_cpu_data.x86 == 0x11) {
|
||||
if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) ||
|
||||
boot_cpu_data.x86 == 0x11) {
|
||||
rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
|
||||
/*
|
||||
* MSR C001_0064+:
|
||||
@@ -300,7 +298,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
|
||||
}
|
||||
|
||||
pss = buffer.pointer;
|
||||
if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
|
||||
if (!pss || pss->type != ACPI_TYPE_PACKAGE) {
|
||||
pr_err("Invalid _PSS data\n");
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
@@ -353,8 +351,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
|
||||
* Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
|
||||
*/
|
||||
if (!px->core_frequency ||
|
||||
((u32)(px->core_frequency * 1000) !=
|
||||
(px->core_frequency * 1000))) {
|
||||
(u32)(px->core_frequency * 1000) != px->core_frequency * 1000) {
|
||||
pr_err(FW_BUG
|
||||
"Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
|
||||
pr->id, px->core_frequency);
|
||||
@@ -456,7 +453,7 @@ int acpi_processor_pstate_control(void)
|
||||
int acpi_processor_notify_smm(struct module *calling_module)
|
||||
{
|
||||
static int is_done;
|
||||
int result;
|
||||
int result = 0;
|
||||
|
||||
if (!acpi_processor_cpufreq_init)
|
||||
return -EBUSY;
|
||||
@@ -464,42 +461,41 @@ int acpi_processor_notify_smm(struct module *calling_module)
|
||||
if (!try_module_get(calling_module))
|
||||
return -EINVAL;
|
||||
|
||||
/* is_done is set to negative if an error occurred,
|
||||
* and to postitive if _no_ error occurred, but SMM
|
||||
* was already notified. This avoids double notification
|
||||
* which might lead to unexpected results...
|
||||
/*
|
||||
* is_done is set to negative if an error occurs and to 1 if no error
|
||||
* occurrs, but SMM has been notified already. This avoids repeated
|
||||
* notification which might lead to unexpected results.
|
||||
*/
|
||||
if (is_done > 0) {
|
||||
module_put(calling_module);
|
||||
return 0;
|
||||
} else if (is_done < 0) {
|
||||
module_put(calling_module);
|
||||
return is_done;
|
||||
}
|
||||
if (is_done != 0) {
|
||||
if (is_done < 0)
|
||||
result = is_done;
|
||||
|
||||
is_done = -EIO;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
result = acpi_processor_pstate_control();
|
||||
if (!result) {
|
||||
pr_debug("No SMI port or pstate_control\n");
|
||||
module_put(calling_module);
|
||||
return 0;
|
||||
}
|
||||
if (result < 0) {
|
||||
module_put(calling_module);
|
||||
return result;
|
||||
if (result <= 0) {
|
||||
if (result) {
|
||||
is_done = result;
|
||||
} else {
|
||||
pr_debug("No SMI port or pstate_control\n");
|
||||
is_done = 1;
|
||||
}
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
/* Success. If there's no _PPC, we need to fear nothing, so
|
||||
* we can allow the cpufreq driver to be rmmod'ed. */
|
||||
is_done = 1;
|
||||
/*
|
||||
* Success. If there _PPC, unloading the cpufreq driver would be risky,
|
||||
* so disallow it in that case.
|
||||
*/
|
||||
if (acpi_processor_ppc_in_use)
|
||||
return 0;
|
||||
|
||||
if (!acpi_processor_ppc_in_use)
|
||||
module_put(calling_module);
|
||||
|
||||
return 0;
|
||||
out_put:
|
||||
module_put(calling_module);
|
||||
return result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_processor_notify_smm);
|
||||
|
||||
int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
|
||||
@@ -517,7 +513,7 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
|
||||
}
|
||||
|
||||
psd = buffer.pointer;
|
||||
if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
|
||||
if (!psd || psd->type != ACPI_TYPE_PACKAGE) {
|
||||
pr_err("Invalid _PSD data\n");
|
||||
result = -EFAULT;
|
||||
goto end;
|
||||
@@ -532,8 +528,7 @@ int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
|
||||
state.length = sizeof(struct acpi_psd_package);
|
||||
state.pointer = pdomain;
|
||||
|
||||
status = acpi_extract_package(&(psd->package.elements[0]),
|
||||
&format, &state);
|
||||
status = acpi_extract_package(&(psd->package.elements[0]), &format, &state);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_err("Invalid _PSD data\n");
|
||||
result = -EFAULT;
|
||||
@@ -716,9 +711,8 @@ int acpi_processor_preregister_performance(
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_processor_preregister_performance);
|
||||
|
||||
int
|
||||
acpi_processor_register_performance(struct acpi_processor_performance
|
||||
*performance, unsigned int cpu)
|
||||
int acpi_processor_register_performance(struct acpi_processor_performance
|
||||
*performance, unsigned int cpu)
|
||||
{
|
||||
struct acpi_processor *pr;
|
||||
|
||||
@@ -751,7 +745,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
|
||||
mutex_unlock(&performance_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_processor_register_performance);
|
||||
|
||||
void acpi_processor_unregister_performance(unsigned int cpu)
|
||||
@@ -761,18 +754,15 @@ void acpi_processor_unregister_performance(unsigned int cpu)
|
||||
mutex_lock(&performance_mutex);
|
||||
|
||||
pr = per_cpu(processors, cpu);
|
||||
if (!pr) {
|
||||
mutex_unlock(&performance_mutex);
|
||||
return;
|
||||
}
|
||||
if (!pr)
|
||||
goto unlock;
|
||||
|
||||
if (pr->performance)
|
||||
kfree(pr->performance->states);
|
||||
|
||||
pr->performance = NULL;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&performance_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_processor_unregister_performance);
|
||||
|
||||
@@ -50,7 +50,7 @@ static int __acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||
|
||||
static int acpi_processor_update_tsd_coord(void)
|
||||
{
|
||||
int count, count_target;
|
||||
int count_target;
|
||||
int retval = 0;
|
||||
unsigned int i, j;
|
||||
cpumask_var_t covered_cpus;
|
||||
@@ -107,7 +107,6 @@ static int acpi_processor_update_tsd_coord(void)
|
||||
|
||||
/* Validate the Domain info */
|
||||
count_target = pdomain->num_processors;
|
||||
count = 1;
|
||||
|
||||
for_each_possible_cpu(j) {
|
||||
if (i == j)
|
||||
@@ -140,7 +139,6 @@ static int acpi_processor_update_tsd_coord(void)
|
||||
|
||||
cpumask_set_cpu(j, covered_cpus);
|
||||
cpumask_set_cpu(j, pthrottling->shared_cpu_map);
|
||||
count++;
|
||||
}
|
||||
for_each_possible_cpu(j) {
|
||||
if (i == j)
|
||||
|
||||
@@ -96,7 +96,7 @@ struct acpi_sbs {
|
||||
|
||||
#define to_acpi_sbs(x) power_supply_get_drvdata(x)
|
||||
|
||||
static int acpi_sbs_remove(struct acpi_device *device);
|
||||
static void acpi_sbs_remove(struct acpi_device *device);
|
||||
static int acpi_battery_get_state(struct acpi_battery *battery);
|
||||
|
||||
static inline int battery_scale(int log)
|
||||
@@ -664,16 +664,16 @@ static int acpi_sbs_add(struct acpi_device *device)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_sbs_remove(struct acpi_device *device)
|
||||
static void acpi_sbs_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_sbs *sbs;
|
||||
int id;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
return;
|
||||
sbs = acpi_driver_data(device);
|
||||
if (!sbs)
|
||||
return -EINVAL;
|
||||
return;
|
||||
mutex_lock(&sbs->lock);
|
||||
acpi_smbus_unregister_callback(sbs->hc);
|
||||
for (id = 0; id < MAX_SBS_BAT; ++id)
|
||||
@@ -682,7 +682,6 @@ static int acpi_sbs_remove(struct acpi_device *device)
|
||||
mutex_unlock(&sbs->lock);
|
||||
mutex_destroy(&sbs->lock);
|
||||
kfree(sbs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -30,7 +30,7 @@ struct acpi_smb_hc {
|
||||
};
|
||||
|
||||
static int acpi_smbus_hc_add(struct acpi_device *device);
|
||||
static int acpi_smbus_hc_remove(struct acpi_device *device);
|
||||
static void acpi_smbus_hc_remove(struct acpi_device *device);
|
||||
|
||||
static const struct acpi_device_id sbs_device_ids[] = {
|
||||
{"ACPI0001", 0},
|
||||
@@ -280,19 +280,18 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
|
||||
|
||||
extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
|
||||
|
||||
static int acpi_smbus_hc_remove(struct acpi_device *device)
|
||||
static void acpi_smbus_hc_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_smb_hc *hc;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
hc = acpi_driver_data(device);
|
||||
acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
|
||||
acpi_os_wait_events_complete();
|
||||
kfree(hc);
|
||||
device->driver_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_acpi_driver(acpi_smb_hc_driver);
|
||||
|
||||
@@ -30,7 +30,7 @@ extern struct acpi_device *acpi_root;
|
||||
#define ACPI_BUS_HID "LNXSYBUS"
|
||||
#define ACPI_BUS_DEVICE_NAME "System Bus"
|
||||
|
||||
#define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page)
|
||||
#define INVALID_ACPI_HANDLE ((acpi_handle)ZERO_PAGE(0))
|
||||
|
||||
static const char *dummy_hid = "device";
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#include "internal.h"
|
||||
@@ -197,7 +198,7 @@ static int param_set_trace_method_name(const char *val,
|
||||
|
||||
static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
return scnprintf(buffer, PAGE_SIZE, "%s\n", acpi_gbl_trace_method_name);
|
||||
return sysfs_emit(buffer, "%s\n", acpi_gbl_trace_method_name);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops param_ops_trace_method = {
|
||||
@@ -992,7 +993,7 @@ static ssize_t force_remove_store(struct kobject *kobj,
|
||||
bool val;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &val);
|
||||
ret = kstrtobool(buf, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -210,6 +210,16 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
|
||||
}
|
||||
break;
|
||||
|
||||
case ACPI_MADT_TYPE_CORE_PIC:
|
||||
{
|
||||
struct acpi_madt_core_pic *p = (struct acpi_madt_core_pic *)header;
|
||||
|
||||
pr_debug("CORE PIC (processor_id[0x%02x] core_id[0x%02x] %s)\n",
|
||||
p->processor_id, p->core_id,
|
||||
(p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
|
||||
header->type);
|
||||
@@ -838,12 +848,11 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
|
||||
/*
|
||||
* acpi_locate_initial_tables()
|
||||
*
|
||||
* find RSDP, find and checksum SDT/XSDT.
|
||||
* checksum all tables, print SDT/XSDT
|
||||
* Get the RSDP, then find and checksum all the ACPI tables.
|
||||
*
|
||||
* result: sdt_entry[] is initialized
|
||||
* result: initial_tables[] is initialized, and points to
|
||||
* a list of ACPI tables.
|
||||
*/
|
||||
|
||||
int __init acpi_locate_initial_tables(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
@@ -74,7 +74,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
|
||||
static struct workqueue_struct *acpi_thermal_pm_queue;
|
||||
|
||||
static int acpi_thermal_add(struct acpi_device *device);
|
||||
static int acpi_thermal_remove(struct acpi_device *device);
|
||||
static void acpi_thermal_remove(struct acpi_device *device);
|
||||
static void acpi_thermal_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
static const struct acpi_device_id thermal_device_ids[] = {
|
||||
@@ -291,7 +291,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
|
||||
"Found critical threshold [%lu]\n",
|
||||
tz->trips.critical.temperature);
|
||||
}
|
||||
if (tz->trips.critical.flags.valid == 1) {
|
||||
if (tz->trips.critical.flags.valid) {
|
||||
if (crt == -1) {
|
||||
tz->trips.critical.flags.valid = 0;
|
||||
} else if (crt > 0) {
|
||||
@@ -1059,19 +1059,18 @@ static int acpi_thermal_add(struct acpi_device *device)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_thermal_remove(struct acpi_device *device)
|
||||
static void acpi_thermal_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_thermal *tz;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
flush_workqueue(acpi_thermal_pm_queue);
|
||||
tz = acpi_driver_data(device);
|
||||
|
||||
acpi_thermal_unregister_thermal_zone(tz);
|
||||
kfree(tz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
@@ -19,11 +19,15 @@ static const struct acpi_device_id tiny_power_button_device_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tiny_power_button_device_ids);
|
||||
|
||||
static int acpi_noop_add_remove(struct acpi_device *device)
|
||||
static int acpi_noop_add(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_noop_remove(struct acpi_device *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void acpi_tiny_power_button_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
kill_cad_pid(power_signal, 1);
|
||||
@@ -34,8 +38,8 @@ static struct acpi_driver acpi_tiny_power_button_driver = {
|
||||
.class = "tiny-power-button",
|
||||
.ids = tiny_power_button_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_noop_add_remove,
|
||||
.remove = acpi_noop_add_remove,
|
||||
.add = acpi_noop_add,
|
||||
.remove = acpi_noop_remove,
|
||||
.notify = acpi_tiny_power_button_notify,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -132,6 +132,10 @@ static int video_detect_force_none(const struct dmi_system_id *d)
|
||||
}
|
||||
|
||||
static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
/*
|
||||
* Models which should use the vendor backlight interface,
|
||||
* because of broken ACPI video backlight control.
|
||||
*/
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
|
||||
.callback = video_detect_force_vendor,
|
||||
@@ -166,6 +170,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugs.launchpad.net/bugs/1000146 */
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus X101CH */
|
||||
.matches = {
|
||||
@@ -190,6 +195,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugs.launchpad.net/bugs/1000146 */
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Asus 1015CX */
|
||||
.matches = {
|
||||
@@ -197,14 +203,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Samsung N150/N210/N220 */
|
||||
@@ -232,14 +230,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Sony VPCEH3U1E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Xiaomi Mi Pad 2 */
|
||||
@@ -249,6 +239,19 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Models which should use the vendor backlight interface,
|
||||
* because of broken native backlight control.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Sony Vaio PCG-FRV35 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Toshiba models with Transflective display, these need to use
|
||||
* the toshiba_acpi vendor driver for proper Transflective handling.
|
||||
@@ -400,8 +403,8 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
|
||||
},
|
||||
},
|
||||
/* https://bugs.launchpad.net/bugs/1894667 */
|
||||
{
|
||||
/* https://bugs.launchpad.net/bugs/1894667 */
|
||||
.callback = video_detect_force_video,
|
||||
/* HP 635 Notebook */
|
||||
.matches = {
|
||||
@@ -609,6 +612,23 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N250P"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=202401 */
|
||||
.callback = video_detect_force_native,
|
||||
/* Sony Vaio VPCEH3U1E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
/* Sony Vaio VPCY11S1E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCY11S1E"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* These Toshibas have a broken acpi-video interface for brightness
|
||||
@@ -671,6 +691,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
/* MSI MS-7721 */
|
||||
@@ -687,6 +715,16 @@ static bool google_cros_ec_present(void)
|
||||
return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C");
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows 8 and newer no longer use the ACPI video interface, so it often
|
||||
* does not work. So on win8+ systems prefer native brightness control.
|
||||
* Chromebooks should always prefer native backlight control.
|
||||
*/
|
||||
static bool prefer_native_over_acpi_video(void)
|
||||
{
|
||||
return acpi_osi_is_win8() || google_cros_ec_present();
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which type of backlight interface to use on this system,
|
||||
* First check cmdline, then dmi quirks, then do autodetect.
|
||||
@@ -732,28 +770,16 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
|
||||
if (apple_gmux_present())
|
||||
return acpi_backlight_apple_gmux;
|
||||
|
||||
/* Chromebooks should always prefer native backlight control. */
|
||||
if (google_cros_ec_present() && native_available)
|
||||
/* Use ACPI video if available, except when native should be preferred. */
|
||||
if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
|
||||
!(native_available && prefer_native_over_acpi_video()))
|
||||
return acpi_backlight_video;
|
||||
|
||||
/* Use native if available */
|
||||
if (native_available)
|
||||
return acpi_backlight_native;
|
||||
|
||||
/* On systems with ACPI video use either native or ACPI video. */
|
||||
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
|
||||
/*
|
||||
* Windows 8 and newer no longer use the ACPI video interface,
|
||||
* so it often does not work. If the ACPI tables are written
|
||||
* for win8 and native brightness ctl is available, use that.
|
||||
*
|
||||
* The native check deliberately is inside the if acpi-video
|
||||
* block on older devices without acpi-video support native
|
||||
* is usually not the best choice.
|
||||
*/
|
||||
if (acpi_osi_is_win8() && native_available)
|
||||
return acpi_backlight_native;
|
||||
else
|
||||
return acpi_backlight_video;
|
||||
}
|
||||
|
||||
/* No ACPI video (old hw), use vendor specific fw methods. */
|
||||
/* No ACPI video/native (old hw), use vendor specific fw methods. */
|
||||
return acpi_backlight_vendor;
|
||||
}
|
||||
|
||||
@@ -765,18 +791,6 @@ EXPORT_SYMBOL(acpi_video_get_backlight_type);
|
||||
|
||||
bool acpi_video_backlight_use_native(void)
|
||||
{
|
||||
/*
|
||||
* Call __acpi_video_get_backlight_type() to let it know that
|
||||
* a native backlight is available.
|
||||
*/
|
||||
__acpi_video_get_backlight_type(true);
|
||||
|
||||
/*
|
||||
* For now just always return true. There is a whole bunch of laptop
|
||||
* models where (video_caps & ACPI_VIDEO_BACKLIGHT) is false causing
|
||||
* __acpi_video_get_backlight_type() to return vendor, while these
|
||||
* models only have a native backlight control.
|
||||
*/
|
||||
return true;
|
||||
return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_video_backlight_use_native);
|
||||
|
||||
@@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
|
||||
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
|
||||
},
|
||||
{
|
||||
/* Lenovo Yoga Tablet 1050F/L */
|
||||
/* Lenovo Yoga Tablet 2 1050F/L */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
|
||||
@@ -319,6 +319,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
|
||||
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
|
||||
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
|
||||
},
|
||||
{
|
||||
/* Lenovo Yoga Tab 3 Pro X90F */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
|
||||
},
|
||||
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
|
||||
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
|
||||
},
|
||||
{
|
||||
/* Medion Lifetab S10346 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
|
||||
/* Way too generic, also match on BIOS data */
|
||||
DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
|
||||
},
|
||||
.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
|
||||
ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
|
||||
},
|
||||
{
|
||||
/* Nextbook Ares 8 */
|
||||
.matches = {
|
||||
@@ -348,6 +369,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = {
|
||||
{ "10EC5640", 0 }, /* RealTek ALC5640 audio codec */
|
||||
{ "INT33F4", 0 }, /* X-Powers AXP288 PMIC */
|
||||
{ "INT33FD", 0 }, /* Intel Crystal Cove PMIC */
|
||||
{ "INT34D3", 0 }, /* Intel Whiskey Cove PMIC */
|
||||
{ "NPCE69A", 0 }, /* Asus Transformer keyboard dock */
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ obj-$(CONFIG_REGMAP) += regmap/
|
||||
obj-$(CONFIG_SOC_BUS) += soc.o
|
||||
obj-$(CONFIG_PINCTRL) += pinctrl.o
|
||||
obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
|
||||
obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o
|
||||
obj-$(CONFIG_GENERIC_MSI_IRQ) += platform-msi.o
|
||||
obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o
|
||||
obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o
|
||||
obj-$(CONFIG_ACPI) += physical_location.o
|
||||
|
||||
@@ -213,7 +213,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
|
||||
err = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, nvec - 1);
|
||||
if (err)
|
||||
platform_msi_free_priv_data(dev);
|
||||
|
||||
@@ -227,7 +227,7 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs);
|
||||
*/
|
||||
void platform_msi_domain_free_irqs(struct device *dev)
|
||||
{
|
||||
msi_domain_free_irqs(dev->msi.domain, dev);
|
||||
msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
|
||||
platform_msi_free_priv_data(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
|
||||
@@ -325,7 +325,7 @@ void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int vir
|
||||
|
||||
msi_lock_descs(data->dev);
|
||||
irq_domain_free_irqs_common(domain, virq, nr_irqs);
|
||||
msi_free_msi_descs_range(data->dev, MSI_DESC_ALL, virq, virq + nr_irqs - 1);
|
||||
msi_free_msi_descs_range(data->dev, virq, virq + nr_irqs - 1);
|
||||
msi_unlock_descs(data->dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
config FSL_MC_BUS
|
||||
bool "QorIQ DPAA2 fsl-mc bus driver"
|
||||
depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86_LOCAL_APIC || PPC)))
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
help
|
||||
Driver to enable the bus infrastructure for the QorIQ DPAA2
|
||||
architecture. The fsl-mc bus driver handles discovery of
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/msi.h>
|
||||
#include <linux/fsl/mc.h>
|
||||
|
||||
#include "fsl-mc-private.h"
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/msi.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/iommu.h>
|
||||
|
||||
@@ -213,21 +213,8 @@ struct irq_domain *fsl_mc_find_msi_domain(struct device *dev)
|
||||
|
||||
int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count)
|
||||
{
|
||||
struct irq_domain *msi_domain;
|
||||
int error;
|
||||
int error = msi_setup_device_data(dev);
|
||||
|
||||
msi_domain = dev_get_msi_domain(dev);
|
||||
if (!msi_domain)
|
||||
return -EINVAL;
|
||||
|
||||
error = msi_setup_device_data(dev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
msi_lock_descs(dev);
|
||||
if (msi_first_desc(dev, MSI_DESC_ALL))
|
||||
error = -EINVAL;
|
||||
msi_unlock_descs(dev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -235,7 +222,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count)
|
||||
* NOTE: Calling this function will trigger the invocation of the
|
||||
* its_fsl_mc_msi_prepare() callback
|
||||
*/
|
||||
error = msi_domain_alloc_irqs(msi_domain, dev, irq_count);
|
||||
error = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, 0, irq_count - 1);
|
||||
|
||||
if (error)
|
||||
dev_err(dev, "Failed to allocate IRQs\n");
|
||||
@@ -244,11 +231,5 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count)
|
||||
|
||||
void fsl_mc_msi_domain_free_irqs(struct device *dev)
|
||||
{
|
||||
struct irq_domain *msi_domain;
|
||||
|
||||
msi_domain = dev_get_msi_domain(dev);
|
||||
if (!msi_domain)
|
||||
return;
|
||||
|
||||
msi_domain_free_irqs(msi_domain, dev);
|
||||
msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
|
||||
}
|
||||
|
||||
@@ -1123,10 +1123,9 @@ static int sonypi_acpi_add(struct acpi_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sonypi_acpi_remove(struct acpi_device *device)
|
||||
static void sonypi_acpi_remove(struct acpi_device *device)
|
||||
{
|
||||
sonypi_acpi_device = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id sonypi_device_ids[] = {
|
||||
|
||||
@@ -713,14 +713,12 @@ static int crb_acpi_add(struct acpi_device *device)
|
||||
return tpm_chip_register(chip);
|
||||
}
|
||||
|
||||
static int crb_acpi_remove(struct acpi_device *device)
|
||||
static void crb_acpi_remove(struct acpi_device *device)
|
||||
{
|
||||
struct device *dev = &device->dev;
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
tpm_chip_unregister(chip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops crb_pm = {
|
||||
|
||||
@@ -462,7 +462,7 @@ config MV_XOR_V2
|
||||
select DMA_ENGINE
|
||||
select DMA_ENGINE_RAID
|
||||
select ASYNC_TX_ENABLE_CHANNEL_SWITCH
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
help
|
||||
Enable support for the Marvell version 2 XOR engine.
|
||||
|
||||
|
||||
@@ -610,7 +610,7 @@ static irqreturn_t hidma_chirq_handler(int chirq, void *arg)
|
||||
return hidma_ll_inthandler(chirq, lldev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ
|
||||
static irqreturn_t hidma_chirq_handler_msi(int chirq, void *arg)
|
||||
{
|
||||
struct hidma_lldev **lldevp = arg;
|
||||
@@ -671,7 +671,7 @@ static int hidma_sysfs_init(struct hidma_dev *dev)
|
||||
return device_create_file(dev->ddev.dev, dev->chid_attrs);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ
|
||||
static void hidma_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
|
||||
{
|
||||
struct device *dev = msi_desc_to_dev(desc);
|
||||
@@ -687,7 +687,7 @@ static void hidma_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)
|
||||
|
||||
static void hidma_free_msis(struct hidma_dev *dmadev)
|
||||
{
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ
|
||||
struct device *dev = dmadev->ddev.dev;
|
||||
int i, virq;
|
||||
|
||||
@@ -704,7 +704,7 @@ static void hidma_free_msis(struct hidma_dev *dmadev)
|
||||
static int hidma_request_msi(struct hidma_dev *dmadev,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
|
||||
#ifdef CONFIG_GENERIC_MSI_IRQ
|
||||
int rc, i, virq;
|
||||
|
||||
rc = platform_msi_domain_alloc_irqs(&pdev->dev, HIDMA_MSI_INTS,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/pci.h>
|
||||
#include <clocksource/hyperv_timer.h>
|
||||
#include <asm/mshyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
struct vmbus_dynid {
|
||||
@@ -2240,7 +2241,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int vmbus_acpi_remove(struct acpi_device *device)
|
||||
static void vmbus_acpi_remove(struct acpi_device *device)
|
||||
{
|
||||
struct resource *cur_res;
|
||||
struct resource *next_res;
|
||||
@@ -2257,8 +2258,6 @@ static int vmbus_acpi_remove(struct acpi_device *device)
|
||||
kfree(cur_res);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vmbus_reserve_fb(void)
|
||||
|
||||
@@ -910,12 +910,12 @@ static int acpi_power_meter_add(struct acpi_device *device)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int acpi_power_meter_remove(struct acpi_device *device)
|
||||
static void acpi_power_meter_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_power_meter_resource *resource;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
return;
|
||||
|
||||
resource = acpi_driver_data(device);
|
||||
hwmon_device_unregister(resource->hwmon_dev);
|
||||
@@ -924,7 +924,6 @@ static int acpi_power_meter_remove(struct acpi_device *device)
|
||||
free_capabilities(resource);
|
||||
|
||||
kfree(resource);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_meter_resume(struct device *dev)
|
||||
|
||||
@@ -187,7 +187,7 @@ struct atk_acpi_input_buf {
|
||||
};
|
||||
|
||||
static int atk_add(struct acpi_device *device);
|
||||
static int atk_remove(struct acpi_device *device);
|
||||
static void atk_remove(struct acpi_device *device);
|
||||
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
|
||||
static int atk_read_value(struct atk_sensor_data *sensor, u64 *value);
|
||||
|
||||
@@ -1344,7 +1344,7 @@ static int atk_add(struct acpi_device *device)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int atk_remove(struct acpi_device *device)
|
||||
static void atk_remove(struct acpi_device *device)
|
||||
{
|
||||
struct atk_data *data = device->driver_data;
|
||||
dev_dbg(&device->dev, "removing...\n");
|
||||
@@ -1359,8 +1359,6 @@ static int atk_remove(struct acpi_device *device)
|
||||
if (atk_ec_ctl(data, 0))
|
||||
dev_err(&device->dev, "Failed to disable EC\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init atk0110_init(void)
|
||||
|
||||
@@ -106,7 +106,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int atlas_acpi_button_remove(struct acpi_device *device)
|
||||
static void atlas_acpi_button_remove(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
@@ -116,8 +116,6 @@ static int atlas_acpi_button_remove(struct acpi_device *device)
|
||||
pr_err("error removing addr spc handler\n");
|
||||
|
||||
input_unregister_device(input_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id atlas_device_ids[] = {
|
||||
|
||||
@@ -389,7 +389,7 @@ config ARM_SMMU_V3
|
||||
depends on ARM64
|
||||
select IOMMU_API
|
||||
select IOMMU_IO_PGTABLE_LPAE
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
help
|
||||
Support for implementations of the ARM System MMU architecture
|
||||
version 3 providing translation support to a PCIe root complex.
|
||||
|
||||
@@ -734,7 +734,6 @@ struct amd_iommu {
|
||||
u8 max_counters;
|
||||
#ifdef CONFIG_IRQ_REMAP
|
||||
struct irq_domain *ir_domain;
|
||||
struct irq_domain *msi_domain;
|
||||
|
||||
struct amd_irte_ops *irte_ops;
|
||||
#endif
|
||||
|
||||
@@ -812,10 +812,10 @@ static void
|
||||
amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu)
|
||||
{
|
||||
if (!irq_remapping_enabled || !dev_is_pci(dev) ||
|
||||
pci_dev_has_special_msi_domain(to_pci_dev(dev)))
|
||||
!pci_dev_has_default_msi_parent_domain(to_pci_dev(dev)))
|
||||
return;
|
||||
|
||||
dev_set_msi_domain(dev, iommu->msi_domain);
|
||||
dev_set_msi_domain(dev, iommu->ir_domain);
|
||||
}
|
||||
|
||||
#else /* CONFIG_IRQ_REMAP */
|
||||
@@ -3294,17 +3294,9 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
|
||||
if (!info)
|
||||
return -EINVAL;
|
||||
if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI &&
|
||||
info->type != X86_IRQ_ALLOC_TYPE_PCI_MSIX)
|
||||
if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* With IRQ remapping enabled, don't need contiguous CPU vectors
|
||||
* to support multiple MSI interrupts.
|
||||
*/
|
||||
if (info->type == X86_IRQ_ALLOC_TYPE_PCI_MSI)
|
||||
info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
|
||||
|
||||
sbdf = get_devid(info);
|
||||
if (sbdf < 0)
|
||||
return -EINVAL;
|
||||
@@ -3656,6 +3648,21 @@ static struct irq_chip amd_ir_chip = {
|
||||
.irq_compose_msi_msg = ir_compose_msi_msg,
|
||||
};
|
||||
|
||||
static const struct msi_parent_ops amdvi_msi_parent_ops = {
|
||||
.supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED |
|
||||
MSI_FLAG_MULTI_PCI_MSI |
|
||||
MSI_FLAG_PCI_IMS,
|
||||
.prefix = "IR-",
|
||||
.init_dev_msi_info = msi_parent_init_dev_msi_info,
|
||||
};
|
||||
|
||||
static const struct msi_parent_ops virt_amdvi_msi_parent_ops = {
|
||||
.supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED |
|
||||
MSI_FLAG_MULTI_PCI_MSI,
|
||||
.prefix = "vIR-",
|
||||
.init_dev_msi_info = msi_parent_init_dev_msi_info,
|
||||
};
|
||||
|
||||
int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
|
||||
{
|
||||
struct fwnode_handle *fn;
|
||||
@@ -3663,16 +3670,21 @@ int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
|
||||
fn = irq_domain_alloc_named_id_fwnode("AMD-IR", iommu->index);
|
||||
if (!fn)
|
||||
return -ENOMEM;
|
||||
iommu->ir_domain = irq_domain_create_tree(fn, &amd_ir_domain_ops, iommu);
|
||||
iommu->ir_domain = irq_domain_create_hierarchy(arch_get_ir_parent_domain(), 0, 0,
|
||||
fn, &amd_ir_domain_ops, iommu);
|
||||
if (!iommu->ir_domain) {
|
||||
irq_domain_free_fwnode(fn);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
iommu->ir_domain->parent = arch_get_ir_parent_domain();
|
||||
iommu->msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain,
|
||||
"AMD-IR-MSI",
|
||||
iommu->index);
|
||||
irq_domain_update_bus_token(iommu->ir_domain, DOMAIN_BUS_AMDVI);
|
||||
iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
|
||||
|
||||
if (amd_iommu_np_cache)
|
||||
iommu->ir_domain->msi_parent_ops = &virt_amdvi_msi_parent_ops;
|
||||
else
|
||||
iommu->ir_domain->msi_parent_ops = &amdvi_msi_parent_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -600,7 +600,6 @@ struct intel_iommu {
|
||||
#ifdef CONFIG_IRQ_REMAP
|
||||
struct ir_table *ir_table; /* Interrupt remapping info */
|
||||
struct irq_domain *ir_domain;
|
||||
struct irq_domain *ir_msi_domain;
|
||||
#endif
|
||||
struct iommu_device iommu; /* IOMMU core code handle */
|
||||
int node;
|
||||
|
||||
@@ -82,6 +82,7 @@ static const struct irq_domain_ops intel_ir_domain_ops;
|
||||
|
||||
static void iommu_disable_irq_remapping(struct intel_iommu *iommu);
|
||||
static int __init parse_ioapics_under_ir(void);
|
||||
static const struct msi_parent_ops dmar_msi_parent_ops, virt_dmar_msi_parent_ops;
|
||||
|
||||
static bool ir_pre_enabled(struct intel_iommu *iommu)
|
||||
{
|
||||
@@ -230,7 +231,7 @@ static struct irq_domain *map_dev_to_ir(struct pci_dev *dev)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd = dmar_find_matched_drhd_unit(dev);
|
||||
|
||||
return drhd ? drhd->iommu->ir_msi_domain : NULL;
|
||||
return drhd ? drhd->iommu->ir_domain : NULL;
|
||||
}
|
||||
|
||||
static int clear_entries(struct irq_2_iommu *irq_iommu)
|
||||
@@ -573,10 +574,14 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)
|
||||
pr_err("IR%d: failed to allocate irqdomain\n", iommu->seq_id);
|
||||
goto out_free_fwnode;
|
||||
}
|
||||
iommu->ir_msi_domain =
|
||||
arch_create_remap_msi_irq_domain(iommu->ir_domain,
|
||||
"INTEL-IR-MSI",
|
||||
iommu->seq_id);
|
||||
|
||||
irq_domain_update_bus_token(iommu->ir_domain, DOMAIN_BUS_DMAR);
|
||||
iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
|
||||
|
||||
if (cap_caching_mode(iommu->cap))
|
||||
iommu->ir_domain->msi_parent_ops = &virt_dmar_msi_parent_ops;
|
||||
else
|
||||
iommu->ir_domain->msi_parent_ops = &dmar_msi_parent_ops;
|
||||
|
||||
ir_table->base = page_address(pages);
|
||||
ir_table->bitmap = bitmap;
|
||||
@@ -620,9 +625,6 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)
|
||||
return 0;
|
||||
|
||||
out_free_ir_domain:
|
||||
if (iommu->ir_msi_domain)
|
||||
irq_domain_remove(iommu->ir_msi_domain);
|
||||
iommu->ir_msi_domain = NULL;
|
||||
irq_domain_remove(iommu->ir_domain);
|
||||
iommu->ir_domain = NULL;
|
||||
out_free_fwnode:
|
||||
@@ -644,13 +646,6 @@ static void intel_teardown_irq_remapping(struct intel_iommu *iommu)
|
||||
struct fwnode_handle *fn;
|
||||
|
||||
if (iommu && iommu->ir_table) {
|
||||
if (iommu->ir_msi_domain) {
|
||||
fn = iommu->ir_msi_domain->fwnode;
|
||||
|
||||
irq_domain_remove(iommu->ir_msi_domain);
|
||||
irq_domain_free_fwnode(fn);
|
||||
iommu->ir_msi_domain = NULL;
|
||||
}
|
||||
if (iommu->ir_domain) {
|
||||
fn = iommu->ir_domain->fwnode;
|
||||
|
||||
@@ -1107,7 +1102,7 @@ static int reenable_irq_remapping(int eim)
|
||||
*/
|
||||
void intel_irq_remap_add_device(struct dmar_pci_notify_info *info)
|
||||
{
|
||||
if (!irq_remapping_enabled || pci_dev_has_special_msi_domain(info->dev))
|
||||
if (!irq_remapping_enabled || !pci_dev_has_default_msi_parent_domain(info->dev))
|
||||
return;
|
||||
|
||||
dev_set_msi_domain(&info->dev->dev, map_dev_to_ir(info->dev));
|
||||
@@ -1334,17 +1329,9 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain,
|
||||
|
||||
if (!info || !iommu)
|
||||
return -EINVAL;
|
||||
if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI &&
|
||||
info->type != X86_IRQ_ALLOC_TYPE_PCI_MSIX)
|
||||
if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* With IRQ remapping enabled, don't need contiguous CPU vectors
|
||||
* to support multiple MSI interrupts.
|
||||
*/
|
||||
if (info->type == X86_IRQ_ALLOC_TYPE_PCI_MSI)
|
||||
info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
|
||||
|
||||
ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -1445,6 +1432,21 @@ static const struct irq_domain_ops intel_ir_domain_ops = {
|
||||
.deactivate = intel_irq_remapping_deactivate,
|
||||
};
|
||||
|
||||
static const struct msi_parent_ops dmar_msi_parent_ops = {
|
||||
.supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED |
|
||||
MSI_FLAG_MULTI_PCI_MSI |
|
||||
MSI_FLAG_PCI_IMS,
|
||||
.prefix = "IR-",
|
||||
.init_dev_msi_info = msi_parent_init_dev_msi_info,
|
||||
};
|
||||
|
||||
static const struct msi_parent_ops virt_dmar_msi_parent_ops = {
|
||||
.supported_flags = X86_VECTOR_MSI_FLAGS_SUPPORTED |
|
||||
MSI_FLAG_MULTI_PCI_MSI,
|
||||
.prefix = "vIR-",
|
||||
.init_dev_msi_info = msi_parent_init_dev_msi_info,
|
||||
};
|
||||
|
||||
/*
|
||||
* Support of Interrupt Remapping Unit Hotplug
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/msi.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_iommu.h>
|
||||
#include <linux/of_pci.h>
|
||||
|
||||
@@ -38,7 +38,7 @@ config ARM_GIC_V3
|
||||
|
||||
config ARM_GIC_V3_ITS
|
||||
bool
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
default ARM_GIC_V3
|
||||
|
||||
config ARM_GIC_V3_ITS_PCI
|
||||
@@ -86,7 +86,7 @@ config ALPINE_MSI
|
||||
|
||||
config AL_FIC
|
||||
bool "Amazon's Annapurna Labs Fabric Interrupt Controller"
|
||||
depends on OF || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_IRQ_CHIP
|
||||
select IRQ_DOMAIN
|
||||
help
|
||||
@@ -375,7 +375,7 @@ config MVEBU_ICU
|
||||
|
||||
config MVEBU_ODMI
|
||||
bool
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
|
||||
config MVEBU_PIC
|
||||
bool
|
||||
@@ -488,7 +488,7 @@ config IMX_MU_MSI
|
||||
default m if ARCH_MXC
|
||||
select IRQ_DOMAIN
|
||||
select IRQ_DOMAIN_HIERARCHY
|
||||
select GENERIC_MSI_IRQ_DOMAIN
|
||||
select GENERIC_MSI_IRQ
|
||||
help
|
||||
Provide a driver for the i.MX Messaging Unit block used as a
|
||||
CPU-to-CPU MSI controller. This requires a specially crafted DT
|
||||
@@ -576,6 +576,7 @@ config IRQ_LOONGARCH_CPU
|
||||
select GENERIC_IRQ_CHIP
|
||||
select IRQ_DOMAIN
|
||||
select GENERIC_IRQ_EFFECTIVE_AFF_MASK
|
||||
select LOONGSON_HTVEC
|
||||
select LOONGSON_LIOINTC
|
||||
select LOONGSON_EIOINTC
|
||||
select LOONGSON_PCH_PIC
|
||||
|
||||
@@ -248,14 +248,14 @@ struct aic_info {
|
||||
bool fast_ipi;
|
||||
};
|
||||
|
||||
static const struct aic_info aic1_info = {
|
||||
static const struct aic_info aic1_info __initconst = {
|
||||
.version = 1,
|
||||
|
||||
.event = AIC_EVENT,
|
||||
.target_cpu = AIC_TARGET_CPU,
|
||||
};
|
||||
|
||||
static const struct aic_info aic1_fipi_info = {
|
||||
static const struct aic_info aic1_fipi_info __initconst = {
|
||||
.version = 1,
|
||||
|
||||
.event = AIC_EVENT,
|
||||
@@ -264,7 +264,7 @@ static const struct aic_info aic1_fipi_info = {
|
||||
.fast_ipi = true,
|
||||
};
|
||||
|
||||
static const struct aic_info aic2_info = {
|
||||
static const struct aic_info aic2_info __initconst = {
|
||||
.version = 2,
|
||||
|
||||
.irq_cfg = AIC2_IRQ_CFG,
|
||||
|
||||
@@ -102,7 +102,7 @@ static int gic_probe(struct platform_device *pdev)
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0)
|
||||
goto rpm_disable;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user