summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpi_apd.c2
-rw-r--r--drivers/acpi/acpi_processor.c42
-rw-r--r--drivers/acpi/processor_pdc.c11
-rw-r--r--drivers/acpi/sleep.c8
-rw-r--r--drivers/acpi/spcr.c13
-rw-r--r--drivers/acpi/sysfs.c17
-rw-r--r--drivers/acpi/viot.c5
7 files changed, 85 insertions, 13 deletions
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index 3bbe2276cac7..80f945cbec8a 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -83,6 +83,8 @@ static int fch_misc_setup(struct apd_private_data *pdata)
if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
GFP_KERNEL);
+ if (!clk_data->name)
+ return -ENOMEM;
strcpy(clk_data->name, obj->string.pointer);
} else {
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index 6737b1cbf6d6..f9aa02cac6d1 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <acpi/processor.h>
@@ -148,6 +149,34 @@ static int acpi_processor_errata(void)
return result;
}
+/* Create a platform device to represent a CPU frequency control mechanism. */
+static void cpufreq_add_device(const char *name)
+{
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_simple(name, PLATFORM_DEVID_NONE, NULL, 0);
+ if (IS_ERR(pdev))
+ pr_info("%s device creation failed: %ld\n", name, PTR_ERR(pdev));
+}
+
+#ifdef CONFIG_X86
+/* Check presence of Processor Clocking Control by searching for \_SB.PCCH. */
+static void __init acpi_pcc_cpufreq_init(void)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, "\\_SB", &handle);
+ if (ACPI_FAILURE(status))
+ return;
+
+ if (acpi_has_method(handle, "PCCH"))
+ cpufreq_add_device("pcc-cpufreq");
+}
+#else
+static void __init acpi_pcc_cpufreq_init(void) {}
+#endif /* CONFIG_X86 */
+
/* Initialization */
#ifdef CONFIG_ACPI_HOTPLUG_CPU
int __weak acpi_map_cpu(acpi_handle handle,
@@ -280,14 +309,22 @@ static int acpi_processor_get_info(struct acpi_device *device)
dev_dbg(&device->dev, "Failed to get CPU physical ID.\n");
pr->id = acpi_map_cpuid(pr->phys_id, pr->acpi_id);
- if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
+ if (!cpu0_initialized) {
cpu0_initialized = 1;
/*
* Handle UP system running SMP kernel, with no CPU
* entry in MADT
*/
- if (invalid_logical_cpuid(pr->id) && (num_online_cpus() == 1))
+ if (!acpi_has_cpu_in_madt() && invalid_logical_cpuid(pr->id) &&
+ (num_online_cpus() == 1))
pr->id = 0;
+ /*
+ * Check availability of Processor Performance Control by
+ * looking at the presence of the _PCT object under the first
+ * processor definition.
+ */
+ if (acpi_has_method(pr->handle, "_PCT"))
+ cpufreq_add_device("acpi-cpufreq");
}
/*
@@ -686,6 +723,7 @@ void __init acpi_processor_init(void)
acpi_processor_check_duplicates();
acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
acpi_scan_add_handler(&processor_container_handler);
+ acpi_pcc_cpufreq_init();
}
#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
index 8c3f82c9fff3..18fb04523f93 100644
--- a/drivers/acpi/processor_pdc.c
+++ b/drivers/acpi/processor_pdc.c
@@ -14,6 +14,8 @@
#include <linux/acpi.h>
#include <acpi/processor.h>
+#include <xen/xen.h>
+
#include "internal.h"
static bool __init processor_physically_present(acpi_handle handle)
@@ -47,6 +49,15 @@ static bool __init processor_physically_present(acpi_handle handle)
return false;
}
+ if (xen_initial_domain())
+ /*
+ * When running as a Xen dom0 the number of processors Linux
+ * sees can be different from the real number of processors on
+ * the system, and we still need to execute _PDC for all of
+ * them.
+ */
+ return xen_processor_present(acpi_id);
+
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
cpuid = acpi_get_cpuid(handle, type, acpi_id);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4ca667251272..72470b9f16c4 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -714,7 +714,13 @@ int acpi_s2idle_begin(void)
int acpi_s2idle_prepare(void)
{
if (acpi_sci_irq_valid()) {
- enable_irq_wake(acpi_sci_irq);
+ int error;
+
+ error = enable_irq_wake(acpi_sci_irq);
+ if (error)
+ pr_warn("Warning: Failed to enable wakeup from IRQ %d: %d\n",
+ acpi_sci_irq, error);
+
acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
}
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index 1eabfcd122ee..cd36a97b0ea2 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -71,7 +71,6 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
/**
* acpi_parse_spcr() - parse ACPI SPCR table and add preferred console
- *
* @enable_earlycon: set up earlycon for the console specified by the table
* @enable_console: setup the console specified by the table.
*
@@ -82,7 +81,6 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
*
* When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called
* from arch initialization code as soon as the DT/ACPI decision is made.
- *
*/
int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
{
@@ -97,9 +95,7 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
if (acpi_disabled)
return -ENODEV;
- status = acpi_get_table(ACPI_SIG_SPCR, 0,
- (struct acpi_table_header **)&table);
-
+ status = acpi_get_table(ACPI_SIG_SPCR, 0, (struct acpi_table_header **)&table);
if (ACPI_FAILURE(status))
return -ENOENT;
@@ -110,12 +106,12 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
u32 bit_width = table->serial_port.access_width;
if (bit_width > ACPI_ACCESS_BIT_MAX) {
- pr_err("Unacceptable wide SPCR Access Width. Defaulting to byte size\n");
+ pr_err(FW_BUG "Unacceptable wide SPCR Access Width. Defaulting to byte size\n");
bit_width = ACPI_ACCESS_BIT_DEFAULT;
}
switch (ACPI_ACCESS_BIT_WIDTH((bit_width))) {
default:
- pr_err("Unexpected SPCR Access Width. Defaulting to byte size\n");
+ pr_err(FW_BUG "Unexpected SPCR Access Width. Defaulting to byte size\n");
fallthrough;
case 8:
iotype = "mmio";
@@ -202,7 +198,8 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
if (xgene_8250_erratum_present(table)) {
iotype = "mmio32";
- /* for xgene v1 and v2 we don't know the clock rate of the
+ /*
+ * For xgene v1 and v2 we don't know the clock rate of the
* UART so don't attempt to change to the baud rate state
* in the table because driver cannot calculate the dividers
*/
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 7f4ff56c9d42..687524b50085 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -458,11 +458,28 @@ static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
}
+static int acpi_ccel_data_init(void *th, struct acpi_data_attr *data_attr)
+{
+ struct acpi_table_ccel *ccel = th;
+
+ if (ccel->header.length < sizeof(struct acpi_table_ccel) ||
+ !ccel->log_area_start_address || !ccel->log_area_minimum_length) {
+ kfree(data_attr);
+ return -EINVAL;
+ }
+ data_attr->addr = ccel->log_area_start_address;
+ data_attr->attr.size = ccel->log_area_minimum_length;
+ data_attr->attr.attr.name = "CCEL";
+
+ return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
+}
+
static struct acpi_data_obj {
char *name;
int (*fn)(void *, struct acpi_data_attr *);
} acpi_data_objs[] = {
{ ACPI_SIG_BERT, acpi_bert_data_init },
+ { ACPI_SIG_CCEL, acpi_ccel_data_init },
};
#define NUM_ACPI_DATA_OBJS ARRAY_SIZE(acpi_data_objs)
diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
index ed752cbbe636..c8025921c129 100644
--- a/drivers/acpi/viot.c
+++ b/drivers/acpi/viot.c
@@ -328,6 +328,7 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
{
u32 epid;
struct viot_endpoint *ep;
+ struct device *aliased_dev = data;
u32 domain_nr = pci_domain_nr(pdev->bus);
list_for_each_entry(ep, &viot_pci_ranges, list) {
@@ -338,7 +339,7 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
epid = ((domain_nr - ep->segment_start) << 16) +
dev_id - ep->bdf_start + ep->endpoint_id;
- return viot_dev_iommu_init(&pdev->dev, ep->viommu,
+ return viot_dev_iommu_init(aliased_dev, ep->viommu,
epid);
}
}
@@ -372,7 +373,7 @@ int viot_iommu_configure(struct device *dev)
{
if (dev_is_pci(dev))
return pci_for_each_dma_alias(to_pci_dev(dev),
- viot_pci_dev_iommu_init, NULL);
+ viot_pci_dev_iommu_init, dev);
else if (dev_is_platform(dev))
return viot_mmio_dev_iommu_init(to_platform_device(dev));
return -ENODEV;