diff options
Diffstat (limited to 'drivers/acpi')
137 files changed, 1920 insertions, 1495 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 4e015c77e48e..5f6158973289 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -155,7 +155,6 @@ config ACPI_EC_DEBUGFS config ACPI_AC tristate "AC Adapter" - depends on X86 select POWER_SUPPLY default y help @@ -168,7 +167,6 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" - depends on X86 select POWER_SUPPLY default y help @@ -333,7 +331,7 @@ config ACPI_CUSTOM_DSDT_FILE depends on !STANDALONE help This option supports a custom DSDT by linking it into the kernel. - See Documentation/acpi/dsdt-override.txt + See Documentation/admin-guide/acpi/dsdt-override.rst Enter the full path name to the file which includes the AmlCode or dsdt_aml_code declaration. @@ -355,7 +353,7 @@ config ACPI_TABLE_UPGRADE This option provides functionality to upgrade arbitrary ACPI tables via initrd. No functional change if no ACPI tables are passed via initrd, therefore it's safe to say Y. - See Documentation/acpi/initrd_table_override.txt for details + See Documentation/admin-guide/acpi/initrd_table_override.rst for details config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD bool "Override ACPI tables from built-in initrd" @@ -365,7 +363,7 @@ config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD This option provides functionality to override arbitrary ACPI tables from built-in uncompressed initrd. - See Documentation/acpi/initrd_table_override.txt for details + See Documentation/admin-guide/acpi/initrd_table_override.rst for details config ACPI_DEBUG bool "Debug Statements" @@ -374,7 +372,7 @@ config ACPI_DEBUG output and increases the kernel size by around 50K. Use the acpi.debug_layer and acpi.debug_level kernel command-line - parameters documented in Documentation/acpi/debug.txt and + parameters documented in Documentation/firmware-guide/acpi/debug.rst and Documentation/admin-guide/kernel-parameters.rst to control the type and amount of debug output. @@ -445,7 +443,7 @@ config ACPI_CUSTOM_METHOD help This debug facility allows ACPI AML methods to be inserted and/or replaced without rebooting the system. For details refer to: - Documentation/acpi/method-customizing.txt. + Documentation/firmware-guide/acpi/method-customizing.rst. NOTE: This option is security sensitive, because it allows arbitrary kernel memory to be written to by root (uid=0) users, allowing them @@ -475,6 +473,7 @@ config ACPI_REDUCED_HARDWARE_ONLY If you are unsure what to do, do not enable this option. source "drivers/acpi/nfit/Kconfig" +source "drivers/acpi/hmat/Kconfig" source "drivers/acpi/apei/Kconfig" source "drivers/acpi/dptf/Kconfig" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index bb857421c2e8..5d361e4e3405 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-$(CONFIG_ACPI_NFIT) += nfit/ +obj-$(CONFIG_ACPI_HMAT) += hmat/ obj-$(CONFIG_ACPI) += acpi_memhotplug.o obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o obj-$(CONFIG_ACPI_BATTERY) += battery.o diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index cdd3136829f1..829f37d36b9f 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 7f77c071709a..49b781a9cd97 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for platform bus type. * * Copyright (C) 2015, Linaro Ltd * Author: Graeme Gregory <graeme.gregory@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> @@ -24,6 +21,15 @@ static const struct acpi_device_id amba_id_list[] = { {"ARMH0061", 0}, /* PL061 GPIO Device */ + {"ARMHC500", 0}, /* ARM CoreSight ETM4x */ + {"ARMHC501", 0}, /* ARM CoreSight ETR */ + {"ARMHC502", 0}, /* ARM CoreSight STM */ + {"ARMHC503", 0}, /* ARM CoreSight Debug */ + {"ARMHC979", 0}, /* ARM CoreSight TPIU */ + {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ + {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ + {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ + {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */ {"", 0}, }; diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index ddf598ae8b6b..7cd0c9ac71ea 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * AMD ACPI support for ACPI2platform device. * * Copyright (c) 2014,2015 AMD Corporation. * Authors: Ken Xue <Ken.Xue@amd.com> * Wu, Jeff <Jeff.Wu@amd.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/clk-provider.h> @@ -17,6 +14,7 @@ #include <linux/clkdev.h> #include <linux/acpi.h> #include <linux/err.h> +#include <linux/io.h> #include <linux/pm.h> #include "internal.h" @@ -59,7 +57,7 @@ struct apd_private_data { static int acpi_apd_setup(struct apd_private_data *pdata) { const struct apd_device_desc *dev_desc = pdata->dev_desc; - struct clk *clk = ERR_PTR(-ENODEV); + struct clk *clk; if (dev_desc->fixed_clk_rate) { clk = clk_register_fixed_rate(&pdata->adev->dev, diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 0980a133916f..33ac6cb428fe 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for CMOS RTC Address Space access * * Copyright (C) 2013, Intel Corporation * Authors: Lan Tianyu <tianyu.lan@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/acpi_configfs.c b/drivers/acpi/acpi_configfs.c index 81bfc6197293..57d9d574d4dd 100644 --- a/drivers/acpi/acpi_configfs.c +++ b/drivers/acpi/acpi_configfs.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI configfs support * * Copyright (c) 2016 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. */ #define pr_fmt(fmt) "ACPI configfs: " fmt @@ -56,11 +53,7 @@ static ssize_t acpi_table_aml_write(struct config_item *cfg, if (!table->header) return -ENOMEM; - ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); - ret = acpi_tb_install_and_load_table( - ACPI_PTR_TO_PHYSADDR(table->header), - ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, - &table->index); + ret = acpi_load_table(table->header); if (ret) { kfree(table->header); table->header = NULL; @@ -109,7 +102,7 @@ static ssize_t acpi_table_signature_show(struct config_item *cfg, char *str) if (!h) return -EINVAL; - return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->signature); + return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->signature); } static ssize_t acpi_table_length_show(struct config_item *cfg, char *str) @@ -170,7 +163,7 @@ static ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg, if (!h) return -EINVAL; - return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->asl_compiler_id); + return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->asl_compiler_id); } static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg, diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index 4a434c23a196..7a265c2171c0 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI AML interfacing support * * Copyright (C) 2015, Intel Corporation * Authors: Lv Zheng <lv.zheng@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ /* #define DEBUG */ @@ -390,7 +387,7 @@ again: return size > 0 ? size : ret; } -static int acpi_aml_thread(void *unsed) +static int acpi_aml_thread(void *unused) { acpi_osd_exec_callback function = NULL; void *context; diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 560fdae8cc59..8596a106a933 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Extended Error Log driver * * Copyright (C) 2013 Intel Corp. * Author: Chen, Gong <gong.chen@intel.com> - * - * This file is licensed under GPLv2. */ #include <linux/module.h> diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index 712fd31674a6..9d6c0fc120d7 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_ipmi.c - ACPI IPMI opregion * * Copyright (C) 2010, 2013 Intel Corporation * Author: Zhao Yakui <yakui.zhao@intel.com> * Lv Zheng <lv.zheng@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/module.h> diff --git a/drivers/acpi/acpi_lpat.c b/drivers/acpi/acpi_lpat.c index 2cd9f738812b..851f67c96097 100644 --- a/drivers/acpi/acpi_lpat.c +++ b/drivers/acpi/acpi_lpat.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * acpi_lpat.c - LPAT table processing functions * * Copyright (C) 2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/export.h> @@ -22,7 +14,7 @@ * LPAT conversion table * * @lpat_table: the temperature_raw mapping table structure - * @raw: the raw value, used as a key to get the temerature from the + * @raw: the raw value, used as a key to get the temperature from the * above mapping table * * A positive converted temperature value will be returned on success, diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c index e43cb71b6972..433376e819bb 100644 --- a/drivers/acpi/acpi_lpit.c +++ b/drivers/acpi/acpi_lpit.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * acpi_lpit.c - LPIT table processing functions * * Copyright (C) 2017 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/cpu.h> @@ -137,7 +129,7 @@ static void lpit_update_residency(struct lpit_residency_info *info, static void lpit_process(u64 begin, u64 end) { - while (begin + sizeof(struct acpi_lpit_native) < end) { + while (begin + sizeof(struct acpi_lpit_native) <= end) { struct acpi_lpit_native *lpit_native = (struct acpi_lpit_native *)begin; if (!lpit_native->header.type && !lpit_native->header.flags) { @@ -156,7 +148,6 @@ static void lpit_process(u64 begin, u64 end) void acpi_init_lpit(void) { acpi_status status; - u64 lpit_begin; struct acpi_table_lpit *lpit; status = acpi_get_table(ACPI_SIG_LPIT, 0, (struct acpi_table_header **)&lpit); @@ -164,6 +155,6 @@ void acpi_init_lpit(void) if (ACPI_FAILURE(status)) return; - lpit_begin = (u64)lpit + sizeof(*lpit); - lpit_process(lpit_begin, lpit_begin + lpit->header.length); + lpit_process((u64)lpit + sizeof(*lpit), + (u64)lpit + lpit->header.length); } diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 1e2a10a06b9d..d696f165a50e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for Intel Lynxpoint LPSS. * * Copyright (C) 2013, Intel Corporation * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> @@ -511,10 +508,10 @@ struct hid_uid { const char *uid; }; -static int match_hid_uid(struct device *dev, void *data) +static int match_hid_uid(struct device *dev, const void *data) { struct acpi_device *adev = ACPI_COMPANION(dev); - struct hid_uid *id = data; + const struct hid_uid *id = data; if (!adev) return 0; @@ -1064,6 +1061,13 @@ static int acpi_lpss_suspend_noirq(struct device *dev) int ret; if (pdata->dev_desc->resume_from_noirq) { + /* + * The driver's ->suspend_late callback will be invoked by + * acpi_lpss_do_suspend_late(), with the assumption that the + * driver really wanted to run that code in ->suspend_noirq, but + * it could not run after acpi_dev_suspend() and the driver + * expected the latter to be called in the "late" phase. + */ ret = acpi_lpss_do_suspend_late(dev); if (ret) return ret; @@ -1094,16 +1098,99 @@ static int acpi_lpss_resume_noirq(struct device *dev) struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; - ret = acpi_subsys_resume_noirq(dev); + /* Follow acpi_subsys_resume_noirq(). */ + if (dev_pm_may_skip_resume(dev)) + return 0; + + if (dev_pm_smart_suspend_and_suspended(dev)) + pm_runtime_set_active(dev); + + ret = pm_generic_resume_noirq(dev); if (ret) return ret; - if (!dev_pm_may_skip_resume(dev) && pdata->dev_desc->resume_from_noirq) - ret = acpi_lpss_do_resume_early(dev); + if (!pdata->dev_desc->resume_from_noirq) + return 0; - return ret; + /* + * The driver's ->resume_early callback will be invoked by + * acpi_lpss_do_resume_early(), with the assumption that the driver + * really wanted to run that code in ->resume_noirq, but it could not + * run before acpi_dev_resume() and the driver expected the latter to be + * called in the "early" phase. + */ + return acpi_lpss_do_resume_early(dev); +} + +static int acpi_lpss_do_restore_early(struct device *dev) +{ + int ret = acpi_lpss_resume(dev); + + return ret ? ret : pm_generic_restore_early(dev); +} + +static int acpi_lpss_restore_early(struct device *dev) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + + if (pdata->dev_desc->resume_from_noirq) + return 0; + + return acpi_lpss_do_restore_early(dev); +} + +static int acpi_lpss_restore_noirq(struct device *dev) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + int ret; + + ret = pm_generic_restore_noirq(dev); + if (ret) + return ret; + + if (!pdata->dev_desc->resume_from_noirq) + return 0; + + /* This is analogous to what happens in acpi_lpss_resume_noirq(). */ + return acpi_lpss_do_restore_early(dev); +} + +static int acpi_lpss_do_poweroff_late(struct device *dev) +{ + int ret = pm_generic_poweroff_late(dev); + + return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev)); } +static int acpi_lpss_poweroff_late(struct device *dev) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + if (pdata->dev_desc->resume_from_noirq) + return 0; + + return acpi_lpss_do_poweroff_late(dev); +} + +static int acpi_lpss_poweroff_noirq(struct device *dev) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + if (pdata->dev_desc->resume_from_noirq) { + /* This is analogous to the acpi_lpss_suspend_noirq() case. */ + int ret = acpi_lpss_do_poweroff_late(dev); + if (ret) + return ret; + } + + return pm_generic_poweroff_noirq(dev); +} #endif /* CONFIG_PM_SLEEP */ static int acpi_lpss_runtime_suspend(struct device *dev) @@ -1137,14 +1224,11 @@ static struct dev_pm_domain acpi_lpss_pm_domain = { .resume_noirq = acpi_lpss_resume_noirq, .resume_early = acpi_lpss_resume_early, .freeze = acpi_subsys_freeze, - .freeze_late = acpi_subsys_freeze_late, - .freeze_noirq = acpi_subsys_freeze_noirq, - .thaw_noirq = acpi_subsys_thaw_noirq, - .poweroff = acpi_subsys_suspend, - .poweroff_late = acpi_lpss_suspend_late, - .poweroff_noirq = acpi_subsys_suspend_noirq, - .restore_noirq = acpi_subsys_resume_noirq, - .restore_early = acpi_lpss_resume_early, + .poweroff = acpi_subsys_poweroff, + .poweroff_late = acpi_lpss_poweroff_late, + .poweroff_noirq = acpi_lpss_poweroff_noirq, + .restore_noirq = acpi_lpss_restore_noirq, + .restore_early = acpi_lpss_restore_early, #endif .runtime_suspend = acpi_lpss_runtime_suspend, .runtime_resume = acpi_lpss_runtime_resume, diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 8fe0960ea572..db013dc21c02 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2004, 2013 Intel Corporation * Author: Naveen B S <naveen.b.s@intel.com> @@ -5,17 +6,6 @@ * * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * * ACPI based HotPlug driver that supports Memory Hotplug * This driver fields notifications from firmware for memory add * and remove operations and alerts the VM of the affected memory diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index a47676a55b84..e7dc0133f817 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * acpi_pad.c ACPI Processor Aggregator Driver * * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #include <linux/kernel.h> @@ -73,6 +64,7 @@ static void power_saving_mwait_init(void) case X86_VENDOR_HYGON: case X86_VENDOR_AMD: case X86_VENDOR_INTEL: + case X86_VENDOR_ZHAOXIN: /* * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1f32caa87686..00ec4f2bf015 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for platform bus type. * @@ -5,10 +6,6 @@ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> * Mathias Nyman <mathias.nyman@linux.intel.com> * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index 67d97c0090a2..f3039b93ff61 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for PNP bus type * * Copyright (C) 2014, Intel Corporation * Authors: Zhang Rui <rui.zhang@intel.com> * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index fc447410ae4d..24f065114d42 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * acpi_processor.c - ACPI processor enumeration support * @@ -7,10 +8,6 @@ * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> * Copyright (C) 2013, Intel Corporation * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index d73afb562ad9..9489ffc06411 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * video.c - ACPI Video Driver * * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 95600309ce42..b5516b04ffc0 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI watchdog table parsing support. * * Copyright (C) 2016, Intel Corporation * Author: Mika Westerberg <mika.westerberg@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #define pr_fmt(fmt) "ACPI: watchdog: " fmt diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 831660179662..c8652f91054e 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -69,7 +69,8 @@ acpi_status acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked); acpi_status -acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); +acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info, + u8 clear_on_enable); acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index d056a1845613..fd3beea93421 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -178,7 +178,6 @@ ACPI_GLOBAL(u8, acpi_gbl_verbose_leak_dump); ACPI_GLOBAL(struct acpi_namespace_node, acpi_gbl_root_node_struct); ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_root_node); ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_fadt_gpe_device); -ACPI_GLOBAL(union acpi_operand_object *, acpi_gbl_module_code_list); extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; extern const struct acpi_predefined_names diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index a2dfbf6b004e..13d513b81589 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -293,7 +293,7 @@ acpi_status (*acpi_internal_method) (struct acpi_walk_state * walk_state); * expected_return_btypes - Allowed type(s) for the return value */ struct acpi_name_info { - char name[ACPI_NAME_SIZE]; + char name[ACPI_NAMESEG_SIZE]; u16 argument_list; u8 expected_btypes; }; @@ -370,7 +370,7 @@ typedef acpi_status (*acpi_object_converter) (struct acpi_namespace_node * converted_object); struct acpi_simple_repair_info { - char name[ACPI_NAME_SIZE]; + char name[ACPI_NAMESEG_SIZE]; u32 unexpected_btypes; u32 package_index; acpi_object_converter object_converter; diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 39812fc4386a..7da1864798a0 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -207,8 +207,6 @@ acpi_ns_dump_object_paths(acpi_object_type type, */ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); -void acpi_ns_exec_module_code_list(void); - /* * nsarguments - Argument count/type checking for predefined/reserved names */ diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c index bb43305cb215..4027eaab18a4 100644 --- a/drivers/acpi/acpica/dbexec.c +++ b/drivers/acpi/acpica/dbexec.c @@ -453,7 +453,7 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags) /* Dump a _PLD buffer if present */ - if (ACPI_COMPARE_NAME + if (ACPI_COMPARE_NAMESEG ((ACPI_CAST_PTR (struct acpi_namespace_node, acpi_gbl_db_method_info.method)->name.ascii), diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c index 004d34d9369b..63fe30e86807 100644 --- a/drivers/acpi/acpica/dbnames.c +++ b/drivers/acpi/acpica/dbnames.c @@ -354,7 +354,7 @@ acpi_status acpi_db_find_name_in_namespace(char *name_arg) char acpi_name[5] = "____"; char *acpi_name_ptr = acpi_name; - if (strlen(name_arg) > ACPI_NAME_SIZE) { + if (strlen(name_arg) > ACPI_NAMESEG_SIZE) { acpi_os_printf("Name must be no longer than 4 characters\n"); return (AE_OK); } diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index a4a24ffe5fae..a1ffed29903b 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -200,9 +200,9 @@ acpi_ds_initialize_objects(u32 table_index, /* DSDT is always the first AML table */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT)) { + if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nInitializing Namespace objects:\n")); + "\nACPI table initialization:\n")); } /* Summary of objects initialized */ diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 62d3aa74277b..344feba29063 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -146,6 +146,7 @@ acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked) * FUNCTION: acpi_ev_add_gpe_reference * * PARAMETERS: gpe_event_info - Add a reference to this GPE + * clear_on_enable - Clear GPE status before enabling it * * RETURN: Status * @@ -155,7 +156,8 @@ acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked) ******************************************************************************/ acpi_status -acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) +acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info, + u8 clear_on_enable) { acpi_status status = AE_OK; @@ -170,6 +172,10 @@ acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) /* Enable on first reference */ + if (clear_on_enable) { + (void)acpi_hw_clear_gpe(gpe_event_info); + } + status = acpi_ev_update_gpe_enable_mask(gpe_event_info); if (ACPI_SUCCESS(status)) { status = acpi_ev_enable_gpe(gpe_event_info); diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 328d1d6123ad..fb15e9e2373b 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -453,7 +453,7 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, continue; } - status = acpi_ev_add_gpe_reference(gpe_event_info); + status = acpi_ev_add_gpe_reference(gpe_event_info, FALSE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index c92d2f6ebe01..b04f982e59fa 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -292,7 +292,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, acpi_status status; u32 gpe_number; u8 temp_gpe_number; - char name[ACPI_NAME_SIZE + 1]; + char name[ACPI_NAMESEG_SIZE + 1]; u8 type; ACPI_FUNCTION_TRACE(ev_match_gpe_method); @@ -310,7 +310,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, * 1) Extract the method name and null terminate it */ ACPI_MOVE_32_TO_32(name, &method_node->name.integer); - name[ACPI_NAME_SIZE] = 0; + name[ACPI_NAMESEG_SIZE] = 0; /* 2) Name must begin with an underscore */ diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 3df00eb6621b..279ef0557aa3 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -971,7 +971,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, ACPI_GPE_DISPATCH_METHOD) || (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) == ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) { - (void)acpi_ev_add_gpe_reference(gpe_event_info); + (void)acpi_ev_add_gpe_reference(gpe_event_info, FALSE); if (ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) { /* Poll edge triggered GPEs to handle existing events */ diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 30a083902f52..710488ec59e9 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -108,7 +108,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) if (gpe_event_info) { if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != ACPI_GPE_DISPATCH_NONE) { - status = acpi_ev_add_gpe_reference(gpe_event_info); + status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE); if (ACPI_SUCCESS(status) && ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) { diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index bd68d66e89f0..6b76be5212a4 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -53,10 +53,10 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs) /* Special case for root */ - size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1; + size_needed = 1 + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1; } else { size_needed = - prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1; + prefix_count + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1; } /* @@ -141,7 +141,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) } for (index = 0; - (index < ACPI_NAME_SIZE) + (index < ACPI_NAMESEG_SIZE) && (acpi_ut_valid_name_char(*aml_address, 0)); index++) { char_buf[index] = *aml_address++; } diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 75192b958544..2566e2d4c780 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -36,6 +36,7 @@ acpi_status acpi_ns_root_initialize(void) acpi_status status; const struct acpi_predefined_names *init_val = NULL; struct acpi_namespace_node *new_node; + struct acpi_namespace_node *prev_node = NULL; union acpi_operand_object *obj_desc; acpi_string val = NULL; @@ -61,12 +62,28 @@ acpi_status acpi_ns_root_initialize(void) */ acpi_gbl_root_node = &acpi_gbl_root_node_struct; - /* Enter the pre-defined names in the name table */ + /* Enter the predefined names in the name table */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); + /* + * Create the initial (default) namespace. + * This namespace looks like something similar to this: + * + * ACPI Namespace (from Namespace Root): + * 0 _GPE Scope 00203160 00 + * 0 _PR_ Scope 002031D0 00 + * 0 _SB_ Device 00203240 00 Notify Object: 0020ADD8 + * 0 _SI_ Scope 002032B0 00 + * 0 _TZ_ Device 00203320 00 + * 0 _REV Integer 00203390 00 = 0000000000000002 + * 0 _OS_ String 00203488 00 Len 14 "Microsoft Windows NT" + * 0 _GL_ Mutex 00203580 00 Object 002035F0 + * 0 _OSI Method 00203678 00 Args 1 Len 0000 Aml 00000000 + */ for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { + status = AE_OK; /* _OSI is optional for now, will be permanent later */ @@ -75,17 +92,32 @@ acpi_status acpi_ns_root_initialize(void) continue; } - status = - acpi_ns_lookup(NULL, ACPI_CAST_PTR(char, init_val->name), - init_val->type, ACPI_IMODE_LOAD_PASS2, - ACPI_NS_NO_UPSEARCH, NULL, &new_node); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not create predefined name %s", - init_val->name)); - continue; + /* + * Create, init, and link the new predefined name + * Note: No need to use acpi_ns_lookup here because all the + * predefined names are at the root level. It is much easier to + * just create and link the new node(s) here. + */ + new_node = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node)); + if (!new_node) { + status = AE_NO_MEMORY; + goto unlock_and_exit; } + ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name); + new_node->descriptor_type = ACPI_DESC_TYPE_NAMED; + new_node->type = init_val->type; + + if (!prev_node) { + acpi_gbl_root_node_struct.child = new_node; + } else { + prev_node->peer = new_node; + } + + new_node->parent = &acpi_gbl_root_node_struct; + prev_node = new_node; + /* * Name entered successfully. If entry in pre_defined_names[] specifies * an initial value, create the initial value. @@ -131,7 +163,7 @@ acpi_status acpi_ns_root_initialize(void) new_node->value = obj_desc->method.param_count; #else - /* Mark this as a very SPECIAL method */ + /* Mark this as a very SPECIAL method (_OSI) */ obj_desc->method.info_flags = ACPI_METHOD_INTERNAL_ONLY; @@ -683,7 +715,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, /* Point to next name segment and make this node current */ - path += ACPI_NAME_SIZE; + path += ACPI_NAMESEG_SIZE; current_node = this_node; } diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 5470213b8e64..6eb63db72249 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -74,6 +74,10 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) ACPI_FUNCTION_NAME(ns_delete_node); + if (!node) { + return_VOID; + } + /* Detach an object if there is one */ acpi_ns_detach_object(node); diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 15070bd0c28a..1b12c172e115 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -70,7 +70,7 @@ void acpi_ns_print_pathname(u32 num_segments, const char *pathname) acpi_os_printf("?"); } - pathname += ACPI_NAME_SIZE; + pathname += ACPI_NAMESEG_SIZE; num_segments--; if (num_segments) { acpi_os_printf("."); diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 6390b7951ebf..63748ac699f7 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -14,11 +14,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nseval") -/* Local prototypes */ -static void -acpi_ns_exec_module_code(union acpi_operand_object *method_obj, - struct acpi_evaluate_info *info); - /******************************************************************************* * * FUNCTION: acpi_ns_evaluate @@ -44,7 +39,6 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, * MUTEX: Locks interpreter * ******************************************************************************/ - acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) { acpi_status status; @@ -310,187 +304,3 @@ cleanup: info->full_pathname = NULL; return_ACPI_STATUS(status); } - -/******************************************************************************* - * - * FUNCTION: acpi_ns_exec_module_code_list - * - * PARAMETERS: None - * - * RETURN: None. Exceptions during method execution are ignored, since - * we cannot abort a table load. - * - * DESCRIPTION: Execute all elements of the global module-level code list. - * Each element is executed as a single control method. - * - * NOTE: With this option enabled, each block of detected executable AML - * code that is outside of any control method is wrapped with a temporary - * control method object and placed on a global list. The methods on this - * list are executed below. - * - * This function executes the module-level code for all tables only after - * all of the tables have been loaded. It is a legacy option and is - * not compatible with other ACPI implementations. See acpi_ns_load_table. - * - * This function will be removed when the legacy option is removed. - * - ******************************************************************************/ - -void acpi_ns_exec_module_code_list(void) -{ - union acpi_operand_object *prev; - union acpi_operand_object *next; - struct acpi_evaluate_info *info; - u32 method_count = 0; - - ACPI_FUNCTION_TRACE(ns_exec_module_code_list); - - /* Exit now if the list is empty */ - - next = acpi_gbl_module_code_list; - if (!next) { - ACPI_DEBUG_PRINT((ACPI_DB_INIT_NAMES, - "Legacy MLC block list is empty\n")); - - return_VOID; - } - - /* Allocate the evaluation information block */ - - info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); - if (!info) { - return_VOID; - } - - /* Walk the list, executing each "method" */ - - while (next) { - prev = next; - next = next->method.mutex; - - /* Clear the link field and execute the method */ - - prev->method.mutex = NULL; - acpi_ns_exec_module_code(prev, info); - method_count++; - - /* Delete the (temporary) method object */ - - acpi_ut_remove_reference(prev); - } - - ACPI_INFO(("Executed %u blocks of module-level executable AML code", - method_count)); - - ACPI_FREE(info); - acpi_gbl_module_code_list = NULL; - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ns_exec_module_code - * - * PARAMETERS: method_obj - Object container for the module-level code - * info - Info block for method evaluation - * - * RETURN: None. Exceptions during method execution are ignored, since - * we cannot abort a table load. - * - * DESCRIPTION: Execute a control method containing a block of module-level - * executable AML code. The control method is temporarily - * installed to the root node, then evaluated. - * - ******************************************************************************/ - -static void -acpi_ns_exec_module_code(union acpi_operand_object *method_obj, - struct acpi_evaluate_info *info) -{ - union acpi_operand_object *parent_obj; - struct acpi_namespace_node *parent_node; - acpi_object_type type; - acpi_status status; - - ACPI_FUNCTION_TRACE(ns_exec_module_code); - - /* - * Get the parent node. We cheat by using the next_object field - * of the method object descriptor. - */ - parent_node = - ACPI_CAST_PTR(struct acpi_namespace_node, - method_obj->method.next_object); - type = acpi_ns_get_type(parent_node); - - /* - * Get the region handler and save it in the method object. We may need - * this if an operation region declaration causes a _REG method to be run. - * - * We can't do this in acpi_ps_link_module_code because - * acpi_gbl_root_node->Object is NULL at PASS1. - */ - if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { - method_obj->method.dispatch.handler = - parent_node->object->device.handler; - } - - /* Must clear next_object (acpi_ns_attach_object needs the field) */ - - method_obj->method.next_object = NULL; - - /* Initialize the evaluation information block */ - - memset(info, 0, sizeof(struct acpi_evaluate_info)); - info->prefix_node = parent_node; - - /* - * Get the currently attached parent object. Add a reference, - * because the ref count will be decreased when the method object - * is installed to the parent node. - */ - parent_obj = acpi_ns_get_attached_object(parent_node); - if (parent_obj) { - acpi_ut_add_reference(parent_obj); - } - - /* Install the method (module-level code) in the parent node */ - - status = - acpi_ns_attach_object(parent_node, method_obj, ACPI_TYPE_METHOD); - if (ACPI_FAILURE(status)) { - goto exit; - } - - /* Execute the parent node as a control method */ - - status = acpi_ns_evaluate(info); - - ACPI_DEBUG_PRINT((ACPI_DB_INIT_NAMES, - "Executed module-level code at %p\n", - method_obj->method.aml_start)); - - /* Delete a possible implicit return value (in slack mode) */ - - if (info->return_object) { - acpi_ut_remove_reference(info->return_object); - } - - /* Detach the temporary method object */ - - acpi_ns_detach_object(parent_node); - - /* Restore the original parent object */ - - if (parent_obj) { - status = acpi_ns_attach_object(parent_node, parent_obj, type); - } else { - parent_node->type = (u8)type; - } - -exit: - if (parent_obj) { - acpi_ut_remove_reference(parent_obj); - } - return_VOID; -} diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 19fb8dda870f..61e9dfc9fe8c 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -55,14 +55,19 @@ acpi_status acpi_ns_initialize_objects(void) ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "Completing Region/Field/Buffer/Package initialization:\n")); + "Final data object initialization: ")); - /* Set all init info to zero */ + /* Clear the info block */ memset(&info, 0, sizeof(struct acpi_init_walk_info)); /* Walk entire namespace from the supplied root */ + /* + * TBD: will become ACPI_TYPE_PACKAGE as this type object + * is now the only one that supports deferred initialization + * (forward references). + */ status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL, &info, NULL); @@ -71,13 +76,8 @@ acpi_status acpi_ns_initialize_objects(void) } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - " Initialized %u/%u Regions %u/%u Fields %u/%u " - "Buffers %u/%u Packages (%u nodes)\n", - info.op_region_init, info.op_region_count, - info.field_init, info.field_count, - info.buffer_init, info.buffer_count, - info.package_init, info.package_count, - info.object_count)); + "Namespace contains %u (0x%X) objects\n", + info.object_count, info.object_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Control Methods found\n%u Op Regions found\n", @@ -382,34 +382,18 @@ acpi_ns_init_one_object(acpi_handle obj_handle, acpi_ex_enter_interpreter(); /* - * Each of these types can contain executable AML code within the - * declaration. + * Only initialization of Package objects can be deferred, in order + * to support forward references. */ switch (type) { - case ACPI_TYPE_REGION: - - info->op_region_init++; - status = acpi_ds_get_region_arguments(obj_desc); - break; - - case ACPI_TYPE_BUFFER_FIELD: - - info->field_init++; - status = acpi_ds_get_buffer_field_arguments(obj_desc); - break; - case ACPI_TYPE_LOCAL_BANK_FIELD: + /* TBD: bank_fields do not require deferred init, remove this code */ + info->field_init++; status = acpi_ds_get_bank_field_arguments(obj_desc); break; - case ACPI_TYPE_BUFFER: - - info->buffer_init++; - status = acpi_ds_get_buffer_arguments(obj_desc); - break; - case ACPI_TYPE_PACKAGE: /* Complete the initialization/resolution of the package object */ @@ -421,8 +405,13 @@ acpi_ns_init_one_object(acpi_handle obj_handle, default: - /* No other types can get here */ + /* No other types should get here */ + status = AE_TYPE; + ACPI_EXCEPTION((AE_INFO, status, + "Opcode is not deferred [%4.4s] (%s)", + acpi_ut_get_node_name(node), + acpi_ut_get_type_name(type))); break; } @@ -478,7 +467,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle, /* We are only looking for methods named _INI */ - if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) { + if (!ACPI_COMPARE_NAMESEG(node->name.ascii, METHOD_NAME__INI)) { return (AE_OK); } @@ -641,7 +630,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle, * Note: We know there is an _INI within this subtree, but it may not be * under this particular device, it may be lower in the branch. */ - if (!ACPI_COMPARE_NAME(device_node->name.ascii, "_SB_") || + if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_") || device_node->parent != acpi_gbl_root_node) { ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, device_node, diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 35fff5c75da1..d7c4d6e8e21e 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -109,18 +109,6 @@ unlock: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Completed Table Object Initialization\n")); - /* - * This case handles the legacy option that groups all module-level - * code blocks together and defers execution until all of the tables - * are loaded. Execute all of these blocks at this time. - * Execute any module-level code that was detected during the table - * load phase. - * - * Note: this option is deprecated and will be eliminated in the - * future. Use of this option can cause problems with AML code that - * depends upon in-order immediate execution of module-level code. - */ - acpi_ns_exec_module_code_list(); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 289c15bb8c6a..370bbc867745 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -108,8 +108,8 @@ acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer) /* Just copy the ACPI name from the Node and zero terminate it */ node_name = acpi_ut_get_node_name(node); - ACPI_MOVE_NAME(buffer->pointer, node_name); - ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; + ACPI_COPY_NAMESEG(buffer->pointer, node_name); + ((char *)buffer->pointer)[ACPI_NAMESEG_SIZE] = 0; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer)); return_ACPI_STATUS(AE_OK); @@ -198,7 +198,7 @@ acpi_ns_build_normalized_path(struct acpi_namespace_node *node, char *full_path, u32 path_size, u8 no_trailing) { u32 length = 0, i; - char name[ACPI_NAME_SIZE]; + char name[ACPI_NAMESEG_SIZE]; u8 do_no_trailing; char c, *left, *right; struct acpi_namespace_node *next_node; @@ -446,7 +446,7 @@ static void acpi_ns_normalize_pathname(char *original_path) /* Do one nameseg at a time */ - for (i = 0; (i < ACPI_NAME_SIZE) && *input_path; i++) { + for (i = 0; (i < ACPI_NAMESEG_SIZE) && *input_path; i++) { if ((i == 0) || (*input_path != '_')) { /* First char is allowed to be underscore */ *new_path = *input_path; new_path++; diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index c0b4f7bedfab..f16cf5e4742c 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -203,7 +203,7 @@ acpi_ns_one_complete_parse(u32 pass_number, /* Found OSDT table, enable the namespace override feature */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) && + if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) && pass_number == ACPI_IMODE_LOAD_PASS1) { walk_state->namespace_override = TRUE; } diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 0aacfa48e20d..be86fea8e4d4 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -316,7 +316,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct this_name = acpi_object_repair_info; while (this_name->object_converter) { - if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) { + if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) { /* Check if we can actually repair this name/type combination */ diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index d5804a6d1d65..8d776256b213 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -25,7 +25,7 @@ acpi_status (*acpi_repair_function) (struct acpi_evaluate_info * info, return_object_ptr); typedef struct acpi_repair_info { - char name[ACPI_NAME_SIZE]; + char name[ACPI_NAMESEG_SIZE]; acpi_repair_function repair_function; } acpi_repair_info; @@ -188,7 +188,7 @@ static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct this_name = acpi_ns_repairable_names; while (this_name->repair_function) { - if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) { + if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) { return (this_name); } diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index e5cef1edf49f..b8d007c84d32 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -178,7 +178,7 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) } } - info->length = (ACPI_NAME_SIZE * info->num_segments) + + info->length = (ACPI_NAMESEG_SIZE * info->num_segments) + 4 + info->num_carats; info->next_external_char = next_external_char; @@ -249,7 +249,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) /* Build the name (minus path separators) */ for (; num_segments; num_segments--) { - for (i = 0; i < ACPI_NAME_SIZE; i++) { + for (i = 0; i < ACPI_NAMESEG_SIZE; i++) { if (ACPI_IS_PATH_SEPARATOR(*external_name) || (*external_name == 0)) { @@ -274,7 +274,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) /* Move on the next segment */ external_name++; - result += ACPI_NAME_SIZE; + result += ACPI_NAMESEG_SIZE; } /* Terminate the string */ @@ -489,12 +489,12 @@ acpi_ns_externalize_name(u32 internal_name_length, /* Copy and validate the 4-char name segment */ - ACPI_MOVE_NAME(&(*converted_name)[j], - &internal_name[names_index]); + ACPI_COPY_NAMESEG(&(*converted_name)[j], + &internal_name[names_index]); acpi_ut_repair_name(&(*converted_name)[j]); - j += ACPI_NAME_SIZE; - names_index += ACPI_NAME_SIZE; + j += ACPI_NAMESEG_SIZE; + names_index += ACPI_NAMESEG_SIZE; } } @@ -560,21 +560,9 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle) void acpi_ns_terminate(void) { acpi_status status; - union acpi_operand_object *prev; - union acpi_operand_object *next; ACPI_FUNCTION_TRACE(ns_terminate); - /* Delete any module-level code blocks */ - - next = acpi_gbl_module_code_list; - while (next) { - prev = next; - next = next->method.mutex; - prev->method.mutex = NULL; /* Clear the Mutex (cheated) field */ - acpi_ut_remove_reference(prev); - } - /* * Free the entire namespace -- all nodes and all objects * attached to the nodes diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index de2d3135d6a9..55b4a5b3331f 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -495,8 +495,8 @@ acpi_status acpi_install_method(u8 *buffer) /* Table must be a DSDT or SSDT */ - if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) && - !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { + if (!ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) && + !ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT)) { return (AE_BAD_HEADER); } diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 9d9d442cd999..e62c7897fdf1 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -150,21 +150,21 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) /* Two name segments */ - end += 1 + (2 * ACPI_NAME_SIZE); + end += 1 + (2 * ACPI_NAMESEG_SIZE); break; case AML_MULTI_NAME_PREFIX: /* Multiple name segments, 4 chars each, count in next byte */ - end += 2 + (*(end + 1) * ACPI_NAME_SIZE); + end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE); break; default: /* Single name segment */ - end += ACPI_NAME_SIZE; + end += ACPI_NAMESEG_SIZE; break; } @@ -522,7 +522,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state ACPI_MOVE_32_TO_32(&name, parser_state->aml); acpi_ps_set_name(field, name); - parser_state->aml += ACPI_NAME_SIZE; + parser_state->aml += ACPI_NAMESEG_SIZE; ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state); diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 1d6f136e4068..c62be3d91712 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -603,10 +603,10 @@ acpi_walk_resources(acpi_handle device_handle, /* Parameter validation */ if (!device_handle || !user_function || !name || - (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && - !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) && - !ACPI_COMPARE_NAME(name, METHOD_NAME__AEI) && - !ACPI_COMPARE_NAME(name, METHOD_NAME__DMA))) { + (!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) && + !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) && + !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) && + !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) { return_ACPI_STATUS(AE_BAD_PARAMETER); } diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index 0cecd0039acf..91a4b984f224 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c @@ -480,7 +480,8 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, /* If a particular signature is expected (DSDT/FACS), it must match */ - if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { + if (signature && + !ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) { ACPI_BIOS_ERROR((AE_INFO, "Invalid signature 0x%X for ACPI table, expected [%s]", table_desc->signature.integer, signature)); @@ -933,19 +934,6 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) status = acpi_ns_load_table(table_index, parent_node); /* - * This case handles the legacy option that groups all module-level - * code blocks together and defers execution until all of the tables - * are loaded. Execute all of these blocks at this time. - * Execute any module-level code that was detected during the table - * load phase. - * - * Note: this option is deprecated and will be eliminated in the - * future. Use of this option can cause problems with AML code that - * depends upon in-order immediate execution of module-level code. - */ - acpi_ns_exec_module_code_list(); - - /* * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is * responsible for discovering any new wake GPEs by running _PRW methods * that may have been loaded by this table. diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 951bd8e1c50a..b2abb40023a6 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -56,7 +56,7 @@ acpi_tb_find_table(char *signature, /* Normalize the input strings */ memset(&header, 0, sizeof(struct acpi_table_header)); - ACPI_MOVE_NAME(header.signature, signature); + ACPI_COPY_NAMESEG(header.signature, signature); strncpy(header.oem_id, oem_id, ACPI_OEM_ID_SIZE); strncpy(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE); @@ -65,7 +65,7 @@ acpi_tb_find_table(char *signature, (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature), - header.signature, ACPI_NAME_SIZE)) { + header.signature, ACPI_NAMESEG_SIZE)) { /* Not the requested table */ @@ -94,14 +94,14 @@ acpi_tb_find_table(char *signature, if (!memcmp (acpi_gbl_root_table_list.tables[i].pointer->signature, - header.signature, ACPI_NAME_SIZE) && (!oem_id[0] - || - !memcmp - (acpi_gbl_root_table_list. - tables[i].pointer-> - oem_id, - header.oem_id, - ACPI_OEM_ID_SIZE)) + header.signature, ACPI_NAMESEG_SIZE) && (!oem_id[0] + || + !memcmp + (acpi_gbl_root_table_list. + tables[i]. + pointer->oem_id, + header.oem_id, + ACPI_OEM_ID_SIZE)) && (!oem_table_id[0] || !memcmp(acpi_gbl_root_table_list.tables[i].pointer-> oem_table_id, header.oem_table_id, diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index be6642bf6366..ef1ffd36ab3f 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -120,7 +120,7 @@ acpi_tb_install_standard_table(acpi_physical_address address, */ if (!reload && acpi_gbl_disable_ssdt_table_install && - ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { + ACPI_COMPARE_NAMESEG(&new_table_desc.signature, ACPI_SIG_SSDT)) { ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X", new_table_desc.signature.ascii, ACPI_FORMAT_UINT64(address))); diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index 9b5df95d881b..4764f849cb78 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c @@ -69,10 +69,10 @@ acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, memcpy(out_header, header, sizeof(struct acpi_table_header)); - acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); + acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE); acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); - acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); + acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE); } /******************************************************************************* @@ -94,7 +94,7 @@ acpi_tb_print_table_header(acpi_physical_address address, { struct acpi_table_header local_header; - if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { + if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ @@ -158,8 +158,8 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) * They are the odd tables, have no standard ACPI header and no checksum */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) { + if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) || + ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) { return (AE_OK); } diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 2469e01310e2..c5f0b8ec70cc 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -332,9 +332,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address) &table_index); if (ACPI_SUCCESS(status) && - ACPI_COMPARE_NAME(&acpi_gbl_root_table_list. - tables[table_index].signature, - ACPI_SIG_FADT)) { + ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list. + tables[table_index].signature, + ACPI_SIG_FADT)) { acpi_gbl_fadt_index = table_index; acpi_tb_parse_fadt(); } diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 36592888f0e7..1640685bf4ae 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -230,7 +230,7 @@ acpi_get_table_header(char *signature, for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { - if (!ACPI_COMPARE_NAME + if (!ACPI_COMPARE_NAMESEG (&(acpi_gbl_root_table_list.tables[i].signature), signature)) { continue; @@ -323,7 +323,7 @@ acpi_get_table(char *signature, i++) { table_desc = &acpi_gbl_root_table_list.tables[i]; - if (!ACPI_COMPARE_NAME(&table_desc->signature, signature)) { + if (!ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) { continue; } diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 1a2592cc3245..ef8f8a9f3c9c 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -118,7 +118,7 @@ acpi_status acpi_tb_load_namespace(void) table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index]; if (!acpi_gbl_root_table_list.current_table_count || - !ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_DSDT) || + !ACPI_COMPARE_NAMESEG(table->signature.ascii, ACPI_SIG_DSDT) || ACPI_FAILURE(acpi_tb_validate_table(table))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; @@ -170,11 +170,12 @@ acpi_status acpi_tb_load_namespace(void) table = &acpi_gbl_root_table_list.tables[i]; if (!table->address || - (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT) - && !ACPI_COMPARE_NAME(table->signature.ascii, - ACPI_SIG_PSDT) - && !ACPI_COMPARE_NAME(table->signature.ascii, - ACPI_SIG_OSDT)) + (!ACPI_COMPARE_NAMESEG + (table->signature.ascii, ACPI_SIG_SSDT) + && !ACPI_COMPARE_NAMESEG(table->signature.ascii, + ACPI_SIG_PSDT) + && !ACPI_COMPARE_NAMESEG(table->signature.ascii, + ACPI_SIG_OSDT)) || ACPI_FAILURE(acpi_tb_validate_table(table))) { continue; } @@ -296,6 +297,17 @@ acpi_status acpi_load_table(struct acpi_table_header *table) status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table), ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &table_index); + + if (ACPI_SUCCESS(status)) { + /* Complete the initialization/resolution of package objects */ + + status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, + ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, 0, + acpi_ns_init_one_package, + NULL, NULL, NULL); + } + return_ACPI_STATUS(status); } @@ -364,7 +376,7 @@ acpi_status acpi_unload_parent_table(acpi_handle object) * only these types can contain AML and thus are the only types * that can create namespace objects. */ - if (ACPI_COMPARE_NAME + if (ACPI_COMPARE_NAMESEG (acpi_gbl_root_table_list.tables[i].signature.ascii, ACPI_SIG_DSDT)) { status = AE_TYPE; diff --git a/drivers/acpi/acpica/utascii.c b/drivers/acpi/acpica/utascii.c index 79d7426fd7bf..f6cd7d4f698b 100644 --- a/drivers/acpi/acpica/utascii.c +++ b/drivers/acpi/acpica/utascii.c @@ -30,7 +30,7 @@ u8 acpi_ut_valid_nameseg(char *name) /* Validate each character in the signature */ - for (i = 0; i < ACPI_NAME_SIZE; i++) { + for (i = 0; i < ACPI_NAMESEG_SIZE; i++) { if (!acpi_ut_valid_name_char(name[i], i)) { return (FALSE); } diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index ad9f77eb554f..65beaa237669 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -78,7 +78,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { "IPMI", /* 0x07 */ "GeneralPurposeIo", /* 0x08 */ "GenericSerialBus", /* 0x09 */ - "PCC" /* 0x0A */ + "PlatformCommChannel" /* 0x0A */ }; const char *acpi_ut_get_region_name(u8 space_id) @@ -239,7 +239,7 @@ const char *acpi_ut_get_node_name(void *object) { struct acpi_namespace_node *node = (struct acpi_namespace_node *)object; - /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */ + /* Must return a string of exactly 4 characters == ACPI_NAMESEG_SIZE */ if (!object) { return ("NULL"); diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index bc124591320e..6f33e7c72327 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -180,7 +180,6 @@ acpi_status acpi_ut_init_globals(void) /* Namespace */ - acpi_gbl_module_code_list = NULL; acpi_gbl_root_node = NULL; acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index afaadc73196b..8638efacdbf4 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -59,10 +59,10 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table) /* These are the only tables that contain executable AML */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) || + if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) || + ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_PSDT) || + ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT) || + ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) || ACPI_IS_OEM_SIG(table->signature)) { return (TRUE); } diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index a9f08f43c685..1b0f68f5ed8c 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c @@ -84,7 +84,7 @@ const union acpi_predefined_info *acpi_ut_match_predefined_method(char *name) this_name = acpi_gbl_predefined_methods; while (this_name->info.name[0]) { - if (ACPI_COMPARE_NAME(name, this_name->info.name)) { + if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) { return (this_name); } @@ -201,7 +201,7 @@ const union acpi_predefined_info *acpi_ut_match_resource_name(char *name) this_name = acpi_gbl_resource_names; while (this_name->info.name[0]) { - if (ACPI_COMPARE_NAME(name, this_name->info.name)) { + if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) { return (this_name); } diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 5bef0b059406..c39b5483045d 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c @@ -141,15 +141,15 @@ void acpi_ut_repair_name(char *name) * Special case for the root node. This can happen if we get an * error during the execution of module-level code. */ - if (ACPI_COMPARE_NAME(name, ACPI_ROOT_PATHNAME)) { + if (ACPI_COMPARE_NAMESEG(name, ACPI_ROOT_PATHNAME)) { return; } - ACPI_MOVE_NAME(&original_name, name); + ACPI_COPY_NAMESEG(&original_name, name); /* Check each character in the name */ - for (i = 0; i < ACPI_NAME_SIZE; i++) { + for (i = 0; i < ACPI_NAMESEG_SIZE; i++) { if (acpi_ut_valid_name_char(name[i], i)) { continue; } diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 9f3b1e3a09de..cf769e94fe0f 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c @@ -211,24 +211,17 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags) ACPI_FUNCTION_TRACE(acpi_initialize_objects); +#ifdef ACPI_OBSOLETE_BEHAVIOR /* - * This case handles the legacy option that groups all module-level - * code blocks together and defers execution until all of the tables - * are loaded. Execute all of these blocks at this time. - * Execute any module-level code that was detected during the table - * load phase. - * - * Note: this option is deprecated and will be eliminated in the - * future. Use of this option can cause problems with AML code that - * depends upon in-order immediate execution of module-level code. + * 05/2019: Removed, initialization now happens at both object + * creation and table load time */ - acpi_ns_exec_module_code_list(); /* * Initialize the objects that remain uninitialized. This * runs the executable AML that may be part of the - * declaration of these objects: - * operation_regions, buffer_fields, Buffers, and Packages. + * declaration of these objects: operation_regions, buffer_fields, + * bank_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { status = acpi_ns_initialize_objects(); @@ -236,6 +229,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags) return_ACPI_STATUS(status); } } +#endif /* * Initialize all device/region objects in the namespace. This runs diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index da370e1d31f4..131c35ee9ed3 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * apei-base.c - ACPI Platform Error Interface (APEI) supporting * infrastructure @@ -15,15 +16,6 @@ * * Copyright (C) 2009, Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/apei/bert.c b/drivers/acpi/apei/bert.c index 0d948d0a41af..1155fb9dcc3a 100644 --- a/drivers/acpi/apei/bert.c +++ b/drivers/acpi/apei/bert.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Boot Error Record Table (BERT) support * @@ -16,9 +17,6 @@ * * For more information about BERT, please refer to ACPI Specification * version 4.0, section 17.3.1 - * - * This file is licensed under GPLv2. - * */ #include <linux/kernel.h> diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 2d4be94f8c00..e430cf4caec2 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Error INJection support * @@ -9,15 +10,6 @@ * * Copyright 2009-2010 Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 6330f557a2c8..d0f3a46716e9 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Error Record Serialization Table debug support * @@ -8,15 +9,6 @@ * * Copyright 2010 Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 389d88e35ffb..2015a0967cbb 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Error Record Serialization Table support * @@ -9,15 +10,6 @@ * * Copyright 2010 Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 0b5ae91fd0fb..a66e00fe31fe 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Generic Hardware Error Source support * @@ -14,15 +15,6 @@ * * Copyright 2010,2011 Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/arm_sdei.h> @@ -353,7 +345,7 @@ static int __ghes_peek_estatus(struct ghes *ghes, return -ENOENT; } - return __ghes_check_estatus(ghes, estatus); + return 0; } static int __ghes_read_estatus(struct acpi_hest_generic_status *estatus, diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 8113ddb14d28..267bdbf6a7bf 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * APEI Hardware Error Souce Table support * @@ -12,15 +13,6 @@ * * Copyright 2009 Intel Corp. * Author: Huang Ying <ying.huang@intel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig index 5a6f80fce0d6..6dba187f4f2e 100644 --- a/drivers/acpi/arm64/Kconfig +++ b/drivers/acpi/arm64/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # ACPI Configuration for ARM64 # diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile index 1017def2ea12..6ff50f4ed947 100644 --- a/drivers/acpi/arm64/Makefile +++ b/drivers/acpi/arm64/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ACPI_IORT) += iort.o obj-$(CONFIG_ACPI_GTDT) += gtdt.o diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index 92f9edf9d11e..01962c63a711 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ARM Specific GTDT table Support * @@ -5,10 +6,6 @@ * Author: Daniel Lezcano <daniel.lezcano@linaro.org> * Fu Wei <fu.wei@linaro.org> * Hanjun Guo <hanjun.guo@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index e48894e002ba..d4551e33fa71 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016, Semihalf * Author: Tomasz Nowicki <tn@semihalf.com> * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * * This file implements early detection/parsing of I/O mapping * reported to OS through firmware via I/O Remapping Table (IORT) * IORT document number: ARM DEN 0049A @@ -356,7 +348,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT || node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX || - node->type == ACPI_IORT_NODE_SMMU_V3) { + node->type == ACPI_IORT_NODE_SMMU_V3 || + node->type == ACPI_IORT_NODE_PMCG) { *id_out = map->output_base; return parent; } @@ -394,6 +387,8 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node) } return smmu->id_mapping_index; + case ACPI_IORT_NODE_PMCG: + return 0; default: return -EINVAL; } @@ -750,31 +745,6 @@ static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias, return 0; } -static int arm_smmu_iort_xlate(struct device *dev, u32 streamid, - struct fwnode_handle *fwnode, - const struct iommu_ops *ops) -{ - int ret = iommu_fwspec_init(dev, fwnode, ops); - - if (!ret) - ret = iommu_fwspec_add_ids(dev, &streamid, 1); - - return ret; -} - -static inline bool iort_iommu_driver_enabled(u8 type) -{ - switch (type) { - case ACPI_IORT_NODE_SMMU_V3: - return IS_BUILTIN(CONFIG_ARM_SMMU_V3); - case ACPI_IORT_NODE_SMMU: - return IS_BUILTIN(CONFIG_ARM_SMMU); - default: - pr_warn("IORT node type %u does not describe an SMMU\n", type); - return false; - } -} - #ifdef CONFIG_IOMMU_API static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev) { @@ -875,15 +845,39 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) return (resv == its->its_count) ? resv : -ENODEV; } -#else -static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) -{ return NULL; } -static inline int iort_add_device_replay(const struct iommu_ops *ops, - struct device *dev) -{ return 0; } -int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) -{ return 0; } -#endif + +static inline bool iort_iommu_driver_enabled(u8 type) +{ + switch (type) { + case ACPI_IORT_NODE_SMMU_V3: + return IS_BUILTIN(CONFIG_ARM_SMMU_V3); + case ACPI_IORT_NODE_SMMU: + return IS_BUILTIN(CONFIG_ARM_SMMU); + default: + pr_warn("IORT node type %u does not describe an SMMU\n", type); + return false; + } +} + +static int arm_smmu_iort_xlate(struct device *dev, u32 streamid, + struct fwnode_handle *fwnode, + const struct iommu_ops *ops) +{ + int ret = iommu_fwspec_init(dev, fwnode, ops); + + if (!ret) + ret = iommu_fwspec_add_ids(dev, &streamid, 1); + + return ret; +} + +static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node) +{ + struct acpi_iort_root_complex *pci_rc; + + pci_rc = (struct acpi_iort_root_complex *)node->node_data; + return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED; +} static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node, u32 streamid) @@ -930,6 +924,93 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) return iort_iommu_xlate(info->dev, parent, streamid); } +/** + * iort_iommu_configure - Set-up IOMMU configuration for a device. + * + * @dev: device to configure + * + * Returns: iommu_ops pointer on configuration success + * NULL on configuration failure + */ +const struct iommu_ops *iort_iommu_configure(struct device *dev) +{ + struct acpi_iort_node *node, *parent; + const struct iommu_ops *ops; + u32 streamid = 0; + int err = -ENODEV; + + /* + * If we already translated the fwspec there + * is nothing left to do, return the iommu_ops. + */ + ops = iort_fwspec_iommu_ops(dev); + if (ops) + return ops; + + if (dev_is_pci(dev)) { + struct pci_bus *bus = to_pci_dev(dev)->bus; + struct iort_pci_alias_info info = { .dev = dev }; + + node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, + iort_match_node_callback, &bus->dev); + if (!node) + return NULL; + + info.node = node; + err = pci_for_each_dma_alias(to_pci_dev(dev), + iort_pci_iommu_init, &info); + + if (!err && iort_pci_rc_supports_ats(node)) + dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS; + } else { + int i = 0; + + node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, + iort_match_node_callback, dev); + if (!node) + return NULL; + + do { + parent = iort_node_map_platform_id(node, &streamid, + IORT_IOMMU_TYPE, + i++); + + if (parent) + err = iort_iommu_xlate(dev, parent, streamid); + } while (parent && !err); + } + + /* + * If we have reason to believe the IOMMU driver missed the initial + * add_device callback for dev, replay it to get things in order. + */ + if (!err) { + ops = iort_fwspec_iommu_ops(dev); + err = iort_add_device_replay(ops, dev); + } + + /* Ignore all other errors apart from EPROBE_DEFER */ + if (err == -EPROBE_DEFER) { + ops = ERR_PTR(err); + } else if (err) { + dev_dbg(dev, "Adding to IOMMU failed: %d\n", err); + ops = NULL; + } + + return ops; +} +#else +static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) +{ return NULL; } +static inline int iort_add_device_replay(const struct iommu_ops *ops, + struct device *dev) +{ return 0; } +int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) +{ return 0; } +const struct iommu_ops *iort_iommu_configure(struct device *dev) +{ return NULL; } +#endif + static int nc_dma_get_range(struct device *dev, u64 *size) { struct acpi_iort_node *node; @@ -1028,79 +1109,6 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset); } -/** - * iort_iommu_configure - Set-up IOMMU configuration for a device. - * - * @dev: device to configure - * - * Returns: iommu_ops pointer on configuration success - * NULL on configuration failure - */ -const struct iommu_ops *iort_iommu_configure(struct device *dev) -{ - struct acpi_iort_node *node, *parent; - const struct iommu_ops *ops; - u32 streamid = 0; - int err = -ENODEV; - - /* - * If we already translated the fwspec there - * is nothing left to do, return the iommu_ops. - */ - ops = iort_fwspec_iommu_ops(dev); - if (ops) - return ops; - - if (dev_is_pci(dev)) { - struct pci_bus *bus = to_pci_dev(dev)->bus; - struct iort_pci_alias_info info = { .dev = dev }; - - node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, - iort_match_node_callback, &bus->dev); - if (!node) - return NULL; - - info.node = node; - err = pci_for_each_dma_alias(to_pci_dev(dev), - iort_pci_iommu_init, &info); - } else { - int i = 0; - - node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, - iort_match_node_callback, dev); - if (!node) - return NULL; - - do { - parent = iort_node_map_platform_id(node, &streamid, - IORT_IOMMU_TYPE, - i++); - - if (parent) - err = iort_iommu_xlate(dev, parent, streamid); - } while (parent && !err); - } - - /* - * If we have reason to believe the IOMMU driver missed the initial - * add_device callback for dev, replay it to get things in order. - */ - if (!err) { - ops = iort_fwspec_iommu_ops(dev); - err = iort_add_device_replay(ops, dev); - } - - /* Ignore all other errors apart from EPROBE_DEFER */ - if (err == -EPROBE_DEFER) { - ops = ERR_PTR(err); - } else if (err) { - dev_dbg(dev, "Adding to IOMMU failed: %d\n", err); - ops = NULL; - } - - return ops; -} - static void __init acpi_iort_register_irq(int hwirq, const char *name, int trigger, struct resource *res) @@ -1218,32 +1226,47 @@ static void __init arm_smmu_v3_init_resources(struct resource *res, } } -static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) +static void __init arm_smmu_v3_dma_configure(struct device *dev, + struct acpi_iort_node *node) { struct acpi_iort_smmu_v3 *smmu; + enum dev_dma_attr attr; /* Retrieve SMMUv3 specific data */ smmu = (struct acpi_iort_smmu_v3 *)node->node_data; - return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE; + attr = (smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE) ? + DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT; + + /* We expect the dma masks to be equivalent for all SMMUv3 set-ups */ + dev->dma_mask = &dev->coherent_dma_mask; + + /* Configure DMA for the page table walker */ + acpi_dma_configure(dev, attr); } #if defined(CONFIG_ACPI_NUMA) /* * set numa proximity domain for smmuv3 device */ -static void __init arm_smmu_v3_set_proximity(struct device *dev, +static int __init arm_smmu_v3_set_proximity(struct device *dev, struct acpi_iort_node *node) { struct acpi_iort_smmu_v3 *smmu; smmu = (struct acpi_iort_smmu_v3 *)node->node_data; if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) { - set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm)); + int node = acpi_map_pxm_to_node(smmu->pxm); + + if (node != NUMA_NO_NODE && !node_online(node)) + return -EINVAL; + + set_dev_node(dev, node); pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n", smmu->base_address, smmu->pxm); } + return 0; } #else #define arm_smmu_v3_set_proximity NULL @@ -1301,30 +1324,96 @@ static void __init arm_smmu_init_resources(struct resource *res, } } -static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node) +static void __init arm_smmu_dma_configure(struct device *dev, + struct acpi_iort_node *node) { struct acpi_iort_smmu *smmu; + enum dev_dma_attr attr; /* Retrieve SMMU specific data */ smmu = (struct acpi_iort_smmu *)node->node_data; - return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK; + attr = (smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK) ? + DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT; + + /* We expect the dma masks to be equivalent for SMMU set-ups */ + dev->dma_mask = &dev->coherent_dma_mask; + + /* Configure DMA for the page table walker */ + acpi_dma_configure(dev, attr); +} + +static int __init arm_smmu_v3_pmcg_count_resources(struct acpi_iort_node *node) +{ + struct acpi_iort_pmcg *pmcg; + + /* Retrieve PMCG specific data */ + pmcg = (struct acpi_iort_pmcg *)node->node_data; + + /* + * There are always 2 memory resources. + * If the overflow_gsiv is present then add that for a total of 3. + */ + return pmcg->overflow_gsiv ? 3 : 2; +} + +static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res, + struct acpi_iort_node *node) +{ + struct acpi_iort_pmcg *pmcg; + + /* Retrieve PMCG specific data */ + pmcg = (struct acpi_iort_pmcg *)node->node_data; + + res[0].start = pmcg->page0_base_address; + res[0].end = pmcg->page0_base_address + SZ_4K - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = pmcg->page1_base_address; + res[1].end = pmcg->page1_base_address + SZ_4K - 1; + res[1].flags = IORESOURCE_MEM; + + if (pmcg->overflow_gsiv) + acpi_iort_register_irq(pmcg->overflow_gsiv, "overflow", + ACPI_EDGE_SENSITIVE, &res[2]); +} + +static struct acpi_platform_list pmcg_plat_info[] __initdata = { + /* HiSilicon Hip08 Platform */ + {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08}, + { } +}; + +static int __init arm_smmu_v3_pmcg_add_platdata(struct platform_device *pdev) +{ + u32 model; + int idx; + + idx = acpi_match_platform_list(pmcg_plat_info); + if (idx >= 0) + model = pmcg_plat_info[idx].data; + else + model = IORT_SMMU_V3_PMCG_GENERIC; + + return platform_device_add_data(pdev, &model, sizeof(model)); } struct iort_dev_config { const char *name; int (*dev_init)(struct acpi_iort_node *node); - bool (*dev_is_coherent)(struct acpi_iort_node *node); + void (*dev_dma_configure)(struct device *dev, + struct acpi_iort_node *node); int (*dev_count_resources)(struct acpi_iort_node *node); void (*dev_init_resources)(struct resource *res, struct acpi_iort_node *node); - void (*dev_set_proximity)(struct device *dev, + int (*dev_set_proximity)(struct device *dev, struct acpi_iort_node *node); + int (*dev_add_platdata)(struct platform_device *pdev); }; static const struct iort_dev_config iort_arm_smmu_v3_cfg __initconst = { .name = "arm-smmu-v3", - .dev_is_coherent = arm_smmu_v3_is_coherent, + .dev_dma_configure = arm_smmu_v3_dma_configure, .dev_count_resources = arm_smmu_v3_count_resources, .dev_init_resources = arm_smmu_v3_init_resources, .dev_set_proximity = arm_smmu_v3_set_proximity, @@ -1332,9 +1421,16 @@ static const struct iort_dev_config iort_arm_smmu_v3_cfg __initconst = { static const struct iort_dev_config iort_arm_smmu_cfg __initconst = { .name = "arm-smmu", - .dev_is_coherent = arm_smmu_is_coherent, + .dev_dma_configure = arm_smmu_dma_configure, .dev_count_resources = arm_smmu_count_resources, - .dev_init_resources = arm_smmu_init_resources + .dev_init_resources = arm_smmu_init_resources, +}; + +static const struct iort_dev_config iort_arm_smmu_v3_pmcg_cfg __initconst = { + .name = "arm-smmu-v3-pmcg", + .dev_count_resources = arm_smmu_v3_pmcg_count_resources, + .dev_init_resources = arm_smmu_v3_pmcg_init_resources, + .dev_add_platdata = arm_smmu_v3_pmcg_add_platdata, }; static __init const struct iort_dev_config *iort_get_dev_cfg( @@ -1345,6 +1441,8 @@ static __init const struct iort_dev_config *iort_get_dev_cfg( return &iort_arm_smmu_v3_cfg; case ACPI_IORT_NODE_SMMU: return &iort_arm_smmu_cfg; + case ACPI_IORT_NODE_PMCG: + return &iort_arm_smmu_v3_pmcg_cfg; default: return NULL; } @@ -1362,15 +1460,17 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node, struct fwnode_handle *fwnode; struct platform_device *pdev; struct resource *r; - enum dev_dma_attr attr; int ret, count; pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO); if (!pdev) return -ENOMEM; - if (ops->dev_set_proximity) - ops->dev_set_proximity(&pdev->dev, node); + if (ops->dev_set_proximity) { + ret = ops->dev_set_proximity(&pdev->dev, node); + if (ret) + goto dev_put; + } count = ops->dev_count_resources(node); @@ -1393,19 +1493,19 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node, goto dev_put; /* - * Add a copy of IORT node pointer to platform_data to - * be used to retrieve IORT data information. + * Platform devices based on PMCG nodes uses platform_data to + * pass the hardware model info to the driver. For others, add + * a copy of IORT node pointer to platform_data to be used to + * retrieve IORT data information. */ - ret = platform_device_add_data(pdev, &node, sizeof(node)); + if (ops->dev_add_platdata) + ret = ops->dev_add_platdata(pdev); + else + ret = platform_device_add_data(pdev, &node, sizeof(node)); + if (ret) goto dev_put; - /* - * We expect the dma masks to be equivalent for - * all SMMUs set-ups - */ - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - fwnode = iort_get_fwnode(node); if (!fwnode) { @@ -1415,11 +1515,8 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node, pdev->dev.fwnode = fwnode; - attr = ops->dev_is_coherent && ops->dev_is_coherent(node) ? - DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT; - - /* Configure DMA for the page table walker */ - acpi_dma_configure(&pdev->dev, attr); + if (ops->dev_dma_configure) + ops->dev_dma_configure(&pdev->dev, node); iort_set_device_domain(&pdev->dev, node); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index cb97b6105f52..558fedf8a7a1 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * battery.c - ACPI Battery Driver (Revision: 2.0) * @@ -5,20 +6,6 @@ * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com> * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c index 75af78361ce5..251f961c28cc 100644 --- a/drivers/acpi/bgrt.c +++ b/drivers/acpi/bgrt.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * BGRT boot graphic support * Authors: Matthew Garrett, Josh Triplett <josh@joshtriplett.org> * Copyright 2012 Red Hat, Inc <mjg@redhat.com> * Copyright 2012 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 995c4d8922b1..ad2c565f5cbe 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * blacklist.c * @@ -7,20 +8,6 @@ * * Copyright (C) 2004 Len Brown <len.brown@intel.com> * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index eec263c9019e..48bc96d45bab 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $) * * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/module.h> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index a19ff3977ac4..4a2cde2c536a 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * button.c - ACPI Button Driver * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define pr_fmt(fmt) "ACPI: button: " fmt @@ -456,8 +443,11 @@ static int acpi_button_resume(struct device *dev) struct acpi_button *button = acpi_driver_data(device); button->suspended = false; - if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) + if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) { + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); acpi_lid_initialize_state(device); + } return 0; } #endif diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index d0918d421f90..0ca9f82de8ba 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -1,18 +1,4 @@ -/* - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ +// SPDX-License-Identifier: GPL-2.0-or-later #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 12c240903c18..9ea5f55d97e3 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * container.c - ACPI Generic Container Driver * @@ -7,20 +8,6 @@ * Copyright (C) 2004 FUJITSU LIMITED * Copyright (C) 2004, 2013 Intel Corp. * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/acpi.h> #include <linux/container.h> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index d4244e7d0e38..15f103d7532b 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * CPPC (Collaborative Processor Performance Control) methods used by CPUfreq drivers. * * (C) Copyright 2014, 2015 Linaro Ltd. * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - * * CPPC describes a few methods for controlling CPU performance using * information from a per CPU table called CPC. This table is described in * the ACPI v5.0+ specification. The table consists of a list of @@ -81,9 +77,9 @@ struct cppc_pcc_data { int refcount; }; -/* Array to represent the PCC channel per subspace id */ +/* Array to represent the PCC channel per subspace ID */ static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES]; -/* The cpu_pcc_subspace_idx containsper CPU subspace id */ +/* The cpu_pcc_subspace_idx contains per CPU subspace ID */ static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx); /* @@ -436,7 +432,7 @@ int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data) return -ENOMEM; /* - * Now that we have _PSD data from all CPUs, lets setup P-state + * Now that we have _PSD data from all CPUs, let's setup P-state * domain info. */ for_each_possible_cpu(i) { @@ -588,7 +584,7 @@ static int register_pcc_channel(int pcc_ss_idx) return -ENOMEM; } - /* Set flag so that we dont come here for each CPU. */ + /* Set flag so that we don't come here for each CPU. */ pcc_data[pcc_ss_idx]->pcc_channel_acquired = true; } @@ -613,7 +609,7 @@ bool __weak cpc_ffh_supported(void) * * Check and allocate the cppc_pcc_data memory. * In some processor configurations it is possible that same subspace - * is shared between multiple CPU's. This is seen especially in CPU's + * is shared between multiple CPUs. This is seen especially in CPUs * with hardware multi-threading support. * * Return: 0 for success, errno for failure @@ -711,7 +707,7 @@ static bool is_cppc_supported(int revision, int num_ent) /** * acpi_cppc_processor_probe - Search for per CPU _CPC objects. - * @pr: Ptr to acpi_processor containing this CPUs logical Id. + * @pr: Ptr to acpi_processor containing this CPU's logical ID. * * Return: 0 for success or negative value for err. */ @@ -728,7 +724,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) acpi_status status; int ret = -EFAULT; - /* Parse the ACPI _CPC table for this cpu. */ + /* Parse the ACPI _CPC table for this CPU. */ status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output, ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(status)) { @@ -840,7 +836,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) if (ret) goto out_free; - /* Register PCC channel once for all PCC subspace id. */ + /* Register PCC channel once for all PCC subspace ID. */ if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) { ret = register_pcc_channel(pcc_subspace_id); if (ret) @@ -860,7 +856,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) goto out_free; } - /* Plug PSD data into this CPUs CPC descriptor. */ + /* Plug PSD data into this CPU's CPC descriptor. */ per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr; ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj, @@ -891,7 +887,7 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe); /** * acpi_cppc_processor_exit - Cleanup CPC structs. - * @pr: Ptr to acpi_processor containing this CPUs logical Id. + * @pr: Ptr to acpi_processor containing this CPU's logical ID. * * Return: Void */ @@ -931,7 +927,7 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit); /** * cpc_read_ffh() - Read FFH register - * @cpunum: cpu number to read + * @cpunum: CPU number to read * @reg: cppc register information * @val: place holder for return value * @@ -946,7 +942,7 @@ int __weak cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) /** * cpc_write_ffh() - Write FFH register - * @cpunum: cpu number to write + * @cpunum: CPU number to write * @reg: cppc register information * @val: value to write * @@ -1093,7 +1089,7 @@ int cppc_get_desired_perf(int cpunum, u64 *desired_perf) EXPORT_SYMBOL_GPL(cppc_get_desired_perf); /** - * cppc_get_perf_caps - Get a CPUs performance capabilities. + * cppc_get_perf_caps - Get a CPU's performance capabilities. * @cpunum: CPU from which to get capabilities info. * @perf_caps: ptr to cppc_perf_caps. See cppc_acpi.h * @@ -1183,7 +1179,7 @@ out_err: EXPORT_SYMBOL_GPL(cppc_get_perf_caps); /** - * cppc_get_perf_ctrs - Read a CPUs performance feedback counters. + * cppc_get_perf_ctrs - Read a CPU's performance feedback counters. * @cpunum: CPU from which to read counters. * @perf_fb_ctrs: ptr to cppc_perf_fb_ctrs. See cppc_acpi.h * @@ -1210,7 +1206,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME]; /* - * If refernce perf register is not supported then we should + * If reference perf register is not supported then we should * use the nominal perf value */ if (!CPC_SUPPORTED(ref_perf_reg)) @@ -1263,7 +1259,7 @@ out_err: EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); /** - * cppc_set_perf - Set a CPUs performance controls. + * cppc_set_perf - Set a CPU's performance controls. * @cpu: CPU for which to set performance controls. * @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h * @@ -1344,7 +1340,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) * executing the Phase-II. * 2. Some other CPU has beaten this CPU to successfully execute the * write_trylock and has already acquired the write_lock. We know for a - * fact it(other CPU acquiring the write_lock) couldn't have happened + * fact it (other CPU acquiring the write_lock) couldn't have happened * before this CPU's Phase-I as we held the read_lock. * 3. Some other CPU executing pcc CMD_READ has stolen the * down_write, in which case, send_pcc_cmd will check for pending diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c index aa972dc5cb7e..b2ef4c2ec955 100644 --- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * custom_method.c - debugfs interface for customizing ACPI control method */ diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 68bb305b977f..d5ecea3715f8 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * debugfs.c - ACPI debugfs interface to userspace. */ diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 824ae985ad93..28cffaaf9d82 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/acpi/device_pm.c - ACPI device power management routines. * @@ -6,15 +7,6 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -53,6 +45,19 @@ const char *acpi_power_state_string(int state) } } +static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state) +{ + unsigned long long psc; + acpi_status status; + + status = acpi_evaluate_integer(device->handle, "_PSC", NULL, &psc); + if (ACPI_FAILURE(status)) + return -ENODEV; + + *state = psc; + return 0; +} + /** * acpi_device_get_power - Get power state of an ACPI device. * @device: Device to get the power state of. @@ -61,10 +66,16 @@ const char *acpi_power_state_string(int state) * This function does not update the device's power.state field, but it may * update its parent's power.state field (when the parent's power state is * unknown and the device's power state turns out to be D0). + * + * Also, it does not update power resource reference counters to ensure that + * the power state returned by it will be persistent and it may return a power + * state shallower than previously set by acpi_device_set_power() for @device + * (if that power state depends on any power resources). */ int acpi_device_get_power(struct acpi_device *device, int *state) { int result = ACPI_STATE_UNKNOWN; + int error; if (!device || !state) return -EINVAL; @@ -81,18 +92,16 @@ int acpi_device_get_power(struct acpi_device *device, int *state) * if available. */ if (device->power.flags.power_resources) { - int error = acpi_power_get_inferred_state(device, &result); + error = acpi_power_get_inferred_state(device, &result); if (error) return error; } if (device->power.flags.explicit_get) { - acpi_handle handle = device->handle; - unsigned long long psc; - acpi_status status; + int psc; - status = acpi_evaluate_integer(handle, "_PSC", NULL, &psc); - if (ACPI_FAILURE(status)) - return -ENODEV; + error = acpi_dev_pm_explicit_get(device, &psc); + if (error) + return error; /* * The power resources settings may indicate a power state @@ -126,7 +135,6 @@ int acpi_device_get_power(struct acpi_device *device, int *state) return 0; } -EXPORT_SYMBOL(acpi_device_get_power); static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state) { @@ -160,7 +168,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) /* Make sure this is a valid target state */ - if (state == device->power.state) { + /* There is a special case for D0 addressed below. */ + if (state > ACPI_STATE_D0 && state == device->power.state) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n", device->pnp.bus_id, acpi_power_state_string(state))); @@ -210,9 +219,15 @@ int acpi_device_set_power(struct acpi_device *device, int state) return -ENODEV; } - result = acpi_dev_pm_explicit_set(device, state); - if (result) - goto end; + /* + * If the device goes from D3hot to D3cold, _PS3 has been + * evaluated for it already, so skip it in that case. + */ + if (device->power.state < ACPI_STATE_D3_HOT) { + result = acpi_dev_pm_explicit_set(device, state); + if (result) + goto end; + } if (device->power.flags.power_resources) result = acpi_power_transition(device, target_state); @@ -222,6 +237,30 @@ int acpi_device_set_power(struct acpi_device *device, int state) if (result) goto end; } + + if (device->power.state == ACPI_STATE_D0) { + int psc; + + /* Nothing to do here if _PSC is not present. */ + if (!device->power.flags.explicit_get) + return 0; + + /* + * The power state of the device was set to D0 last + * time, but that might have happened before a + * system-wide transition involving the platform + * firmware, so it may be necessary to evaluate _PS0 + * for the device here. However, use extra care here + * and evaluate _PSC to check the device's current power + * state, and only invoke _PS0 if the evaluation of _PSC + * is successful and it returns a power state different + * from D0. + */ + result = acpi_dev_pm_explicit_get(device, &psc); + if (result || psc == ACPI_STATE_D0) + return 0; + } + result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0); } @@ -414,7 +453,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) if (adev->wakeup.flags.notifier_present) { pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup()); if (adev->wakeup.context.func) { - acpi_handle_debug(handle, "Running %pF for %s\n", + acpi_handle_debug(handle, "Running %pS for %s\n", adev->wakeup.context.func, dev_name(adev->wakeup.context.dev)); adev->wakeup.context.func(&adev->wakeup.context); @@ -728,6 +767,9 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev, goto out; } + acpi_handle_debug(adev->handle, "GPE%2X enabled for wakeup\n", + (unsigned int)wakeup->gpe_number); + inc: wakeup->enable_count++; @@ -949,8 +991,8 @@ static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev) u32 sys_target = acpi_target_system_state(); int ret, state; - if (!pm_runtime_suspended(dev) || !adev || - device_may_wakeup(dev) != !!adev->wakeup.prepare_count) + if (!pm_runtime_suspended(dev) || !adev || (adev->wakeup.flags.valid && + device_may_wakeup(dev) != !!adev->wakeup.prepare_count)) return true; if (sys_target == ACPI_STATE_S0) @@ -1078,7 +1120,7 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_noirq); * acpi_subsys_resume_noirq - Run the device driver's "noirq" resume callback. * @dev: Device to handle. */ -int acpi_subsys_resume_noirq(struct device *dev) +static int acpi_subsys_resume_noirq(struct device *dev) { if (dev_pm_may_skip_resume(dev)) return 0; @@ -1093,7 +1135,6 @@ int acpi_subsys_resume_noirq(struct device *dev) return pm_generic_resume_noirq(dev); } -EXPORT_SYMBOL_GPL(acpi_subsys_resume_noirq); /** * acpi_subsys_resume_early - Resume device using ACPI. @@ -1103,12 +1144,11 @@ EXPORT_SYMBOL_GPL(acpi_subsys_resume_noirq); * generic early resume procedure for it during system transition into the * working state. */ -int acpi_subsys_resume_early(struct device *dev) +static int acpi_subsys_resume_early(struct device *dev) { int ret = acpi_dev_resume(dev); return ret ? ret : pm_generic_resume_early(dev); } -EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); /** * acpi_subsys_freeze - Run the device driver's freeze callback. @@ -1117,65 +1157,81 @@ EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); int acpi_subsys_freeze(struct device *dev) { /* - * This used to be done in acpi_subsys_prepare() for all devices and - * some drivers may depend on it, so do it here. Ideally, however, - * runtime-suspended devices should not be touched during freeze/thaw - * transitions. + * Resume all runtime-suspended devices before creating a snapshot + * image of system memory, because the restore kernel generally cannot + * be expected to always handle them consistently and they need to be + * put into the runtime-active metastate during system resume anyway, + * so it is better to ensure that the state saved in the image will be + * always consistent with that. */ - if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) - pm_runtime_resume(dev); + pm_runtime_resume(dev); return pm_generic_freeze(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_freeze); /** - * acpi_subsys_freeze_late - Run the device driver's "late" freeze callback. - * @dev: Device to handle. + * acpi_subsys_restore_early - Restore device using ACPI. + * @dev: Device to restore. */ -int acpi_subsys_freeze_late(struct device *dev) +int acpi_subsys_restore_early(struct device *dev) { + int ret = acpi_dev_resume(dev); + return ret ? ret : pm_generic_restore_early(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_restore_early); - if (dev_pm_smart_suspend_and_suspended(dev)) - return 0; +/** + * acpi_subsys_poweroff - Run the device driver's poweroff callback. + * @dev: Device to handle. + * + * Follow PCI and resume devices from runtime suspend before running their + * system poweroff callbacks, unless the driver can cope with runtime-suspended + * devices during system suspend and there are no ACPI-specific reasons for + * resuming them. + */ +int acpi_subsys_poweroff(struct device *dev) +{ + if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || + acpi_dev_needs_resume(dev, ACPI_COMPANION(dev))) + pm_runtime_resume(dev); - return pm_generic_freeze_late(dev); + return pm_generic_poweroff(dev); } -EXPORT_SYMBOL_GPL(acpi_subsys_freeze_late); +EXPORT_SYMBOL_GPL(acpi_subsys_poweroff); /** - * acpi_subsys_freeze_noirq - Run the device driver's "noirq" freeze callback. + * acpi_subsys_poweroff_late - Run the device driver's poweroff callback. * @dev: Device to handle. + * + * Carry out the generic late poweroff procedure for @dev and use ACPI to put + * it into a low-power state during system transition into a sleep state. */ -int acpi_subsys_freeze_noirq(struct device *dev) +static int acpi_subsys_poweroff_late(struct device *dev) { + int ret; if (dev_pm_smart_suspend_and_suspended(dev)) return 0; - return pm_generic_freeze_noirq(dev); + ret = pm_generic_poweroff_late(dev); + if (ret) + return ret; + + return acpi_dev_suspend(dev, device_may_wakeup(dev)); } -EXPORT_SYMBOL_GPL(acpi_subsys_freeze_noirq); /** - * acpi_subsys_thaw_noirq - Run the device driver's "noirq" thaw callback. - * @dev: Device to handle. + * acpi_subsys_poweroff_noirq - Run the driver's "noirq" poweroff callback. + * @dev: Device to suspend. */ -int acpi_subsys_thaw_noirq(struct device *dev) +static int acpi_subsys_poweroff_noirq(struct device *dev) { - /* - * If the device is in runtime suspend, the "thaw" code may not work - * correctly with it, so skip the driver callback and make the PM core - * skip all of the subsequent "thaw" callbacks for the device. - */ - if (dev_pm_smart_suspend_and_suspended(dev)) { - dev_pm_skip_next_resume_phases(dev); + if (dev_pm_smart_suspend_and_suspended(dev)) return 0; - } - return pm_generic_thaw_noirq(dev); + return pm_generic_poweroff_noirq(dev); } -EXPORT_SYMBOL_GPL(acpi_subsys_thaw_noirq); #endif /* CONFIG_PM_SLEEP */ static struct dev_pm_domain acpi_general_pm_domain = { @@ -1191,14 +1247,10 @@ static struct dev_pm_domain acpi_general_pm_domain = { .resume_noirq = acpi_subsys_resume_noirq, .resume_early = acpi_subsys_resume_early, .freeze = acpi_subsys_freeze, - .freeze_late = acpi_subsys_freeze_late, - .freeze_noirq = acpi_subsys_freeze_noirq, - .thaw_noirq = acpi_subsys_thaw_noirq, - .poweroff = acpi_subsys_suspend, - .poweroff_late = acpi_subsys_suspend_late, - .poweroff_noirq = acpi_subsys_suspend_noirq, - .restore_noirq = acpi_subsys_resume_noirq, - .restore_early = acpi_subsys_resume_early, + .poweroff = acpi_subsys_poweroff, + .poweroff_late = acpi_subsys_poweroff_late, + .poweroff_noirq = acpi_subsys_poweroff_noirq, + .restore_early = acpi_subsys_restore_early, #endif }, }; diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 8940054d6250..96869f1538b9 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/acpi/device_sysfs.c - ACPI device sysfs attributes and modalias. * @@ -7,15 +8,6 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -428,8 +420,10 @@ static ssize_t acpi_device_adr_show(struct device *dev, { struct acpi_device *acpi_dev = to_acpi_device(dev); - return sprintf(buf, "0x%08x\n", - (unsigned int)(acpi_dev->pnp.bus_address)); + if (acpi_dev->pnp.bus_address > U32_MAX) + return sprintf(buf, "0x%016llx\n", acpi_dev->pnp.bus_address); + else + return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address); } static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index e3fc1f045e1c..e3414131bfca 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * dock.c - ACPI dock station driver * * Copyright (C) 2006, 2014, Intel Corp. * Author: Kristen Carlson Accardi <kristen.c.accardi@intel.com> * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/dptf/Makefile b/drivers/acpi/dptf/Makefile index e6032e47e83f..1a9b0a2b25bf 100644 --- a/drivers/acpi/dptf/Makefile +++ b/drivers/acpi/dptf/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ACPI) += int340x_thermal.o obj-$(CONFIG_DPTF_POWER) += dptf_power.o diff --git a/drivers/acpi/dptf/dptf_power.c b/drivers/acpi/dptf/dptf_power.c index e1c242568341..eb58fc475a03 100644 --- a/drivers/acpi/dptf/dptf_power.c +++ b/drivers/acpi/dptf/dptf_power.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * dptf_power: DPTF platform power driver * Copyright (c) 2016, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #include <linux/kernel.h> @@ -31,8 +22,7 @@ static ssize_t name##_show(struct device *dev,\ struct device_attribute *attr,\ char *buf)\ {\ - struct platform_device *pdev = to_platform_device(dev);\ - struct acpi_device *acpi_dev = platform_get_drvdata(pdev);\ + struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ unsigned long long val;\ acpi_status status;\ \ diff --git a/drivers/acpi/dptf/int340x_thermal.c b/drivers/acpi/dptf/int340x_thermal.c index 0aa7c2e62e95..5c7a90186e3c 100644 --- a/drivers/acpi/dptf/int340x_thermal.c +++ b/drivers/acpi/dptf/int340x_thermal.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI support for int340x thermal drivers * * Copyright (C) 2014, Intel Corporation * Authors: Zhang Rui <rui.zhang@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 48d4815603e5..c33756ed3304 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * ec.c - ACPI Embedded Controller Driver (v3) * @@ -9,20 +10,6 @@ * 2001, 2002 Andy Grover <andrew.grover@intel.com> * 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * Copyright (C) 2008 Alexey Starikovskiy <astarikovskiy@suse.de> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Uncomment next line to get verbose printout */ diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 23faa66ea772..fd39c14493ab 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -1,11 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ec_sys.c * * Copyright (C) 2010 SUSE Products GmbH/Novell * Author: * Thomas Renninger <trenn@suse.de> - * - * This work is licensed under the terms of the GNU GPL, version 2. */ #include <linux/kernel.h> diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 5a127f3f2d5c..47f21599f2ab 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -131,8 +131,8 @@ int acpi_bus_generate_netlink_event(const char *device_class, event = nla_data(attr); memset(event, 0, sizeof(struct acpi_genl_event)); - strcpy(event->device_class, device_class); - strcpy(event->bus_id, bus_id); + strscpy(event->device_class, device_class, sizeof(event->device_class)); + strscpy(event->bus_id, bus_id, sizeof(event->bus_id)); event->type = type; event->data = data; diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c index f13ba2c07667..aba0d0027586 100644 --- a/drivers/acpi/evged.c +++ b/drivers/acpi/evged.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Generic Event Device for ACPI. * * Copyright (c) 2016, The Linux Foundation. All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * Generic Event Device allows platforms to handle interrupts in ACPI * ASL statements. It follows very similar to _EVT method approach * from GPIO events. All interrupts are listed in _CRS and the handler @@ -37,7 +29,6 @@ * } * } * } - * */ #include <linux/err.h> diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index fe0183d48dcd..816b0803f7fb 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_fan.c - ACPI Fan Driver ($Revision: 29 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index edd10b3c7ec8..36b24b0658cb 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Link physical devices with ACPI devices support * * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com> * Copyright (c) 2005 Intel Corp. - * - * This file is released under the GPLv2. */ #include <linux/acpi_iort.h> diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index 5c67a6d8f803..cf148287e2ba 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI Hardware Error Device (PNP0C33) Driver * @@ -6,15 +7,6 @@ * * ACPI Hardware Error Device is used to report some hardware errors * notified via SCI, mainly the corrected errors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/acpi/hmat/Kconfig b/drivers/acpi/hmat/Kconfig new file mode 100644 index 000000000000..95a29964dbea --- /dev/null +++ b/drivers/acpi/hmat/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +config ACPI_HMAT + bool "ACPI Heterogeneous Memory Attribute Table Support" + depends on ACPI_NUMA + select HMEM_REPORTING + help + If set, this option has the kernel parse and report the + platform's ACPI HMAT (Heterogeneous Memory Attributes Table), + register memory initiators with their targets, and export + performance attributes through the node's sysfs device if + provided. diff --git a/drivers/acpi/hmat/Makefile b/drivers/acpi/hmat/Makefile new file mode 100644 index 000000000000..1c20ef36a385 --- /dev/null +++ b/drivers/acpi/hmat/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_ACPI_HMAT) := hmat.o diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c new file mode 100644 index 000000000000..96b7d39a97c6 --- /dev/null +++ b/drivers/acpi/hmat/hmat.c @@ -0,0 +1,666 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Intel Corporation. + * + * Heterogeneous Memory Attributes Table (HMAT) representation + * + * This program parses and reports the platform's HMAT tables, and registers + * the applicable attributes with the node's interfaces. + */ + +#include <linux/acpi.h> +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/list_sort.h> +#include <linux/node.h> +#include <linux/sysfs.h> + +static __initdata u8 hmat_revision; + +static __initdata LIST_HEAD(targets); +static __initdata LIST_HEAD(initiators); +static __initdata LIST_HEAD(localities); + +/* + * The defined enum order is used to prioritize attributes to break ties when + * selecting the best performing node. + */ +enum locality_types { + WRITE_LATENCY, + READ_LATENCY, + WRITE_BANDWIDTH, + READ_BANDWIDTH, +}; + +static struct memory_locality *localities_types[4]; + +struct memory_target { + struct list_head node; + unsigned int memory_pxm; + unsigned int processor_pxm; + struct node_hmem_attrs hmem_attrs; +}; + +struct memory_initiator { + struct list_head node; + unsigned int processor_pxm; +}; + +struct memory_locality { + struct list_head node; + struct acpi_hmat_locality *hmat_loc; +}; + +static __init struct memory_initiator *find_mem_initiator(unsigned int cpu_pxm) +{ + struct memory_initiator *initiator; + + list_for_each_entry(initiator, &initiators, node) + if (initiator->processor_pxm == cpu_pxm) + return initiator; + return NULL; +} + +static __init struct memory_target *find_mem_target(unsigned int mem_pxm) +{ + struct memory_target *target; + + list_for_each_entry(target, &targets, node) + if (target->memory_pxm == mem_pxm) + return target; + return NULL; +} + +static __init void alloc_memory_initiator(unsigned int cpu_pxm) +{ + struct memory_initiator *initiator; + + if (pxm_to_node(cpu_pxm) == NUMA_NO_NODE) + return; + + initiator = find_mem_initiator(cpu_pxm); + if (initiator) + return; + + initiator = kzalloc(sizeof(*initiator), GFP_KERNEL); + if (!initiator) + return; + + initiator->processor_pxm = cpu_pxm; + list_add_tail(&initiator->node, &initiators); +} + +static __init void alloc_memory_target(unsigned int mem_pxm) +{ + struct memory_target *target; + + if (pxm_to_node(mem_pxm) == NUMA_NO_NODE) + return; + + target = find_mem_target(mem_pxm); + if (target) + return; + + target = kzalloc(sizeof(*target), GFP_KERNEL); + if (!target) + return; + + target->memory_pxm = mem_pxm; + target->processor_pxm = PXM_INVAL; + list_add_tail(&target->node, &targets); +} + +static __init const char *hmat_data_type(u8 type) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + return "Access Latency"; + case ACPI_HMAT_READ_LATENCY: + return "Read Latency"; + case ACPI_HMAT_WRITE_LATENCY: + return "Write Latency"; + case ACPI_HMAT_ACCESS_BANDWIDTH: + return "Access Bandwidth"; + case ACPI_HMAT_READ_BANDWIDTH: + return "Read Bandwidth"; + case ACPI_HMAT_WRITE_BANDWIDTH: + return "Write Bandwidth"; + default: + return "Reserved"; + } +} + +static __init const char *hmat_data_type_suffix(u8 type) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + return " nsec"; + case ACPI_HMAT_ACCESS_BANDWIDTH: + case ACPI_HMAT_READ_BANDWIDTH: + case ACPI_HMAT_WRITE_BANDWIDTH: + return " MB/s"; + default: + return ""; + } +} + +static __init u32 hmat_normalize(u16 entry, u64 base, u8 type) +{ + u32 value; + + /* + * Check for invalid and overflow values + */ + if (entry == 0xffff || !entry) + return 0; + else if (base > (UINT_MAX / (entry))) + return 0; + + /* + * Divide by the base unit for version 1, convert latency from + * picosenonds to nanoseconds if revision 2. + */ + value = entry * base; + if (hmat_revision == 1) { + if (value < 10) + return 0; + value = DIV_ROUND_UP(value, 10); + } else if (hmat_revision == 2) { + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + value = DIV_ROUND_UP(value, 1000); + break; + default: + break; + } + } + return value; +} + +static __init void hmat_update_target_access(struct memory_target *target, + u8 type, u32 value) +{ + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + target->hmem_attrs.read_latency = value; + target->hmem_attrs.write_latency = value; + break; + case ACPI_HMAT_READ_LATENCY: + target->hmem_attrs.read_latency = value; + break; + case ACPI_HMAT_WRITE_LATENCY: + target->hmem_attrs.write_latency = value; + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + target->hmem_attrs.read_bandwidth = value; + target->hmem_attrs.write_bandwidth = value; + break; + case ACPI_HMAT_READ_BANDWIDTH: + target->hmem_attrs.read_bandwidth = value; + break; + case ACPI_HMAT_WRITE_BANDWIDTH: + target->hmem_attrs.write_bandwidth = value; + break; + default: + break; + } +} + +static __init void hmat_add_locality(struct acpi_hmat_locality *hmat_loc) +{ + struct memory_locality *loc; + + loc = kzalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { + pr_notice_once("Failed to allocate HMAT locality\n"); + return; + } + + loc->hmat_loc = hmat_loc; + list_add_tail(&loc->node, &localities); + + switch (hmat_loc->data_type) { + case ACPI_HMAT_ACCESS_LATENCY: + localities_types[READ_LATENCY] = loc; + localities_types[WRITE_LATENCY] = loc; + break; + case ACPI_HMAT_READ_LATENCY: + localities_types[READ_LATENCY] = loc; + break; + case ACPI_HMAT_WRITE_LATENCY: + localities_types[WRITE_LATENCY] = loc; + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + localities_types[READ_BANDWIDTH] = loc; + localities_types[WRITE_BANDWIDTH] = loc; + break; + case ACPI_HMAT_READ_BANDWIDTH: + localities_types[READ_BANDWIDTH] = loc; + break; + case ACPI_HMAT_WRITE_BANDWIDTH: + localities_types[WRITE_BANDWIDTH] = loc; + break; + default: + break; + } +} + +static __init int hmat_parse_locality(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_locality *hmat_loc = (void *)header; + struct memory_target *target; + unsigned int init, targ, total_size, ipds, tpds; + u32 *inits, *targs, value; + u16 *entries; + u8 type, mem_hier; + + if (hmat_loc->header.length < sizeof(*hmat_loc)) { + pr_notice("HMAT: Unexpected locality header length: %d\n", + hmat_loc->header.length); + return -EINVAL; + } + + type = hmat_loc->data_type; + mem_hier = hmat_loc->flags & ACPI_HMAT_MEMORY_HIERARCHY; + ipds = hmat_loc->number_of_initiator_Pds; + tpds = hmat_loc->number_of_target_Pds; + total_size = sizeof(*hmat_loc) + sizeof(*entries) * ipds * tpds + + sizeof(*inits) * ipds + sizeof(*targs) * tpds; + if (hmat_loc->header.length < total_size) { + pr_notice("HMAT: Unexpected locality header length:%d, minimum required:%d\n", + hmat_loc->header.length, total_size); + return -EINVAL; + } + + pr_info("HMAT: Locality: Flags:%02x Type:%s Initiator Domains:%d Target Domains:%d Base:%lld\n", + hmat_loc->flags, hmat_data_type(type), ipds, tpds, + hmat_loc->entry_base_unit); + + inits = (u32 *)(hmat_loc + 1); + targs = inits + ipds; + entries = (u16 *)(targs + tpds); + for (init = 0; init < ipds; init++) { + alloc_memory_initiator(inits[init]); + for (targ = 0; targ < tpds; targ++) { + value = hmat_normalize(entries[init * tpds + targ], + hmat_loc->entry_base_unit, + type); + pr_info(" Initiator-Target[%d-%d]:%d%s\n", + inits[init], targs[targ], value, + hmat_data_type_suffix(type)); + + if (mem_hier == ACPI_HMAT_MEMORY) { + target = find_mem_target(targs[targ]); + if (target && target->processor_pxm == inits[init]) + hmat_update_target_access(target, type, value); + } + } + } + + if (mem_hier == ACPI_HMAT_MEMORY) + hmat_add_locality(hmat_loc); + + return 0; +} + +static __init int hmat_parse_cache(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_cache *cache = (void *)header; + struct node_cache_attrs cache_attrs; + u32 attrs; + + if (cache->header.length < sizeof(*cache)) { + pr_notice("HMAT: Unexpected cache header length: %d\n", + cache->header.length); + return -EINVAL; + } + + attrs = cache->cache_attributes; + pr_info("HMAT: Cache: Domain:%d Size:%llu Attrs:%08x SMBIOS Handles:%d\n", + cache->memory_PD, cache->cache_size, attrs, + cache->number_of_SMBIOShandles); + + cache_attrs.size = cache->cache_size; + cache_attrs.level = (attrs & ACPI_HMAT_CACHE_LEVEL) >> 4; + cache_attrs.line_size = (attrs & ACPI_HMAT_CACHE_LINE_SIZE) >> 16; + + switch ((attrs & ACPI_HMAT_CACHE_ASSOCIATIVITY) >> 8) { + case ACPI_HMAT_CA_DIRECT_MAPPED: + cache_attrs.indexing = NODE_CACHE_DIRECT_MAP; + break; + case ACPI_HMAT_CA_COMPLEX_CACHE_INDEXING: + cache_attrs.indexing = NODE_CACHE_INDEXED; + break; + case ACPI_HMAT_CA_NONE: + default: + cache_attrs.indexing = NODE_CACHE_OTHER; + break; + } + + switch ((attrs & ACPI_HMAT_WRITE_POLICY) >> 12) { + case ACPI_HMAT_CP_WB: + cache_attrs.write_policy = NODE_CACHE_WRITE_BACK; + break; + case ACPI_HMAT_CP_WT: + cache_attrs.write_policy = NODE_CACHE_WRITE_THROUGH; + break; + case ACPI_HMAT_CP_NONE: + default: + cache_attrs.write_policy = NODE_CACHE_WRITE_OTHER; + break; + } + + node_add_cache(pxm_to_node(cache->memory_PD), &cache_attrs); + return 0; +} + +static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_proximity_domain *p = (void *)header; + struct memory_target *target = NULL; + + if (p->header.length != sizeof(*p)) { + pr_notice("HMAT: Unexpected address range header length: %d\n", + p->header.length); + return -EINVAL; + } + + if (hmat_revision == 1) + pr_info("HMAT: Memory (%#llx length %#llx) Flags:%04x Processor Domain:%d Memory Domain:%d\n", + p->reserved3, p->reserved4, p->flags, p->processor_PD, + p->memory_PD); + else + pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", + p->flags, p->processor_PD, p->memory_PD); + + if (p->flags & ACPI_HMAT_MEMORY_PD_VALID) { + target = find_mem_target(p->memory_PD); + if (!target) { + pr_debug("HMAT: Memory Domain missing from SRAT\n"); + return -EINVAL; + } + } + if (target && p->flags & ACPI_HMAT_PROCESSOR_PD_VALID) { + int p_node = pxm_to_node(p->processor_PD); + + if (p_node == NUMA_NO_NODE) { + pr_debug("HMAT: Invalid Processor Domain\n"); + return -EINVAL; + } + target->processor_pxm = p_node; + } + + return 0; +} + +static int __init hmat_parse_subtable(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_hmat_structure *hdr = (void *)header; + + if (!hdr) + return -EINVAL; + + switch (hdr->type) { + case ACPI_HMAT_TYPE_PROXIMITY: + return hmat_parse_proximity_domain(header, end); + case ACPI_HMAT_TYPE_LOCALITY: + return hmat_parse_locality(header, end); + case ACPI_HMAT_TYPE_CACHE: + return hmat_parse_cache(header, end); + default: + return -EINVAL; + } +} + +static __init int srat_parse_mem_affinity(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_srat_mem_affinity *ma = (void *)header; + + if (!ma) + return -EINVAL; + if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) + return 0; + alloc_memory_target(ma->proximity_domain); + return 0; +} + +static __init u32 hmat_initiator_perf(struct memory_target *target, + struct memory_initiator *initiator, + struct acpi_hmat_locality *hmat_loc) +{ + unsigned int ipds, tpds, i, idx = 0, tdx = 0; + u32 *inits, *targs; + u16 *entries; + + ipds = hmat_loc->number_of_initiator_Pds; + tpds = hmat_loc->number_of_target_Pds; + inits = (u32 *)(hmat_loc + 1); + targs = inits + ipds; + entries = (u16 *)(targs + tpds); + + for (i = 0; i < ipds; i++) { + if (inits[i] == initiator->processor_pxm) { + idx = i; + break; + } + } + + if (i == ipds) + return 0; + + for (i = 0; i < tpds; i++) { + if (targs[i] == target->memory_pxm) { + tdx = i; + break; + } + } + if (i == tpds) + return 0; + + return hmat_normalize(entries[idx * tpds + tdx], + hmat_loc->entry_base_unit, + hmat_loc->data_type); +} + +static __init bool hmat_update_best(u8 type, u32 value, u32 *best) +{ + bool updated = false; + + if (!value) + return false; + + switch (type) { + case ACPI_HMAT_ACCESS_LATENCY: + case ACPI_HMAT_READ_LATENCY: + case ACPI_HMAT_WRITE_LATENCY: + if (!*best || *best > value) { + *best = value; + updated = true; + } + break; + case ACPI_HMAT_ACCESS_BANDWIDTH: + case ACPI_HMAT_READ_BANDWIDTH: + case ACPI_HMAT_WRITE_BANDWIDTH: + if (!*best || *best < value) { + *best = value; + updated = true; + } + break; + } + + return updated; +} + +static int initiator_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct memory_initiator *ia; + struct memory_initiator *ib; + unsigned long *p_nodes = priv; + + ia = list_entry(a, struct memory_initiator, node); + ib = list_entry(b, struct memory_initiator, node); + + set_bit(ia->processor_pxm, p_nodes); + set_bit(ib->processor_pxm, p_nodes); + + return ia->processor_pxm - ib->processor_pxm; +} + +static __init void hmat_register_target_initiators(struct memory_target *target) +{ + static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); + struct memory_initiator *initiator; + unsigned int mem_nid, cpu_nid; + struct memory_locality *loc = NULL; + u32 best = 0; + int i; + + mem_nid = pxm_to_node(target->memory_pxm); + /* + * If the Address Range Structure provides a local processor pxm, link + * only that one. Otherwise, find the best performance attributes and + * register all initiators that match. + */ + if (target->processor_pxm != PXM_INVAL) { + cpu_nid = pxm_to_node(target->processor_pxm); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + return; + } + + if (list_empty(&localities)) + return; + + /* + * We need the initiator list sorted so we can use bitmap_clear for + * previously set initiators when we find a better memory accessor. + * We'll also use the sorting to prime the candidate nodes with known + * initiators. + */ + bitmap_zero(p_nodes, MAX_NUMNODES); + list_sort(p_nodes, &initiators, initiator_cmp); + for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { + loc = localities_types[i]; + if (!loc) + continue; + + best = 0; + list_for_each_entry(initiator, &initiators, node) { + u32 value; + + if (!test_bit(initiator->processor_pxm, p_nodes)) + continue; + + value = hmat_initiator_perf(target, initiator, loc->hmat_loc); + if (hmat_update_best(loc->hmat_loc->data_type, value, &best)) + bitmap_clear(p_nodes, 0, initiator->processor_pxm); + if (value != best) + clear_bit(initiator->processor_pxm, p_nodes); + } + if (best) + hmat_update_target_access(target, loc->hmat_loc->data_type, best); + } + + for_each_set_bit(i, p_nodes, MAX_NUMNODES) { + cpu_nid = pxm_to_node(i); + register_memory_node_under_compute_node(mem_nid, cpu_nid, 0); + } +} + +static __init void hmat_register_target_perf(struct memory_target *target) +{ + unsigned mem_nid = pxm_to_node(target->memory_pxm); + node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0); +} + +static __init void hmat_register_targets(void) +{ + struct memory_target *target; + + list_for_each_entry(target, &targets, node) { + hmat_register_target_initiators(target); + hmat_register_target_perf(target); + } +} + +static __init void hmat_free_structures(void) +{ + struct memory_target *target, *tnext; + struct memory_locality *loc, *lnext; + struct memory_initiator *initiator, *inext; + + list_for_each_entry_safe(target, tnext, &targets, node) { + list_del(&target->node); + kfree(target); + } + + list_for_each_entry_safe(initiator, inext, &initiators, node) { + list_del(&initiator->node); + kfree(initiator); + } + + list_for_each_entry_safe(loc, lnext, &localities, node) { + list_del(&loc->node); + kfree(loc); + } +} + +static __init int hmat_init(void) +{ + struct acpi_table_header *tbl; + enum acpi_hmat_type i; + acpi_status status; + + if (srat_disabled()) + return 0; + + status = acpi_get_table(ACPI_SIG_SRAT, 0, &tbl); + if (ACPI_FAILURE(status)) + return 0; + + if (acpi_table_parse_entries(ACPI_SIG_SRAT, + sizeof(struct acpi_table_srat), + ACPI_SRAT_TYPE_MEMORY_AFFINITY, + srat_parse_mem_affinity, 0) < 0) + goto out_put; + acpi_put_table(tbl); + + status = acpi_get_table(ACPI_SIG_HMAT, 0, &tbl); + if (ACPI_FAILURE(status)) + goto out_put; + + hmat_revision = tbl->revision; + switch (hmat_revision) { + case 1: + case 2: + break; + default: + pr_notice("Ignoring HMAT: Unknown revision:%d\n", hmat_revision); + goto out_put; + } + + for (i = ACPI_HMAT_TYPE_PROXIMITY; i < ACPI_HMAT_TYPE_RESERVED; i++) { + if (acpi_table_parse_entries(ACPI_SIG_HMAT, + sizeof(struct acpi_table_hmat), i, + hmat_parse_subtable, 0) < 0) { + pr_notice("Ignoring HMAT: Invalid table"); + goto out_put; + } + } + hmat_register_targets(); +out_put: + hmat_free_structures(); + acpi_put_table(tbl); + return 0; +} +subsys_initcall(hmat_init); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6eaf06db7752..f4c2fe6be4f2 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -1,18 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * acpi/internal.h * For use by Linux/ACPI infrastructure, not drivers * * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #ifndef _ACPI_INTERNAL_H_ @@ -148,8 +139,15 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state); int acpi_power_on_resources(struct acpi_device *device, int state); int acpi_power_transition(struct acpi_device *device, int state); +/* -------------------------------------------------------------------------- + Device Power Management + -------------------------------------------------------------------------- */ +int acpi_device_get_power(struct acpi_device *device, int *state); int acpi_wakeup_device_init(void); +/* -------------------------------------------------------------------------- + Processor + -------------------------------------------------------------------------- */ #ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC void acpi_early_processor_set_pdc(void); #else diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c index 3595aa9c7c18..a690c7b18623 100644 --- a/drivers/acpi/ioapic.c +++ b/drivers/acpi/ioapic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * IOAPIC/IOxAPIC/IOSAPIC driver * @@ -6,10 +7,6 @@ * * Copyright (C) 2014 Intel Corporation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * Based on original drivers/pci/ioapic.c * Yinghai Lu <yinghai@kernel.org> * Jiang Liu <jiang.liu@intel.com> diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c index c3b2222e2129..e209081d644b 100644 --- a/drivers/acpi/irq.c +++ b/drivers/acpi/irq.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI GSI IRQ layer * * Copyright (C) 2015 ARM Ltd. * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> #include <linux/irq.h> @@ -295,3 +292,29 @@ void __init acpi_set_irq_model(enum acpi_irq_model_id model, acpi_irq_model = model; acpi_gsi_domain_id = fwnode; } + +/** + * acpi_irq_create_hierarchy - Create a hierarchical IRQ domain with the default + * GSI domain as its parent. + * @flags: Irq domain flags associated with the domain + * @size: Size of the domain. + * @fwnode: Optional fwnode of the interrupt controller + * @ops: Pointer to the interrupt domain callbacks + * @host_data: Controller private data pointer + */ +struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags, + unsigned int size, + struct fwnode_handle *fwnode, + const struct irq_domain_ops *ops, + void *host_data) +{ + struct irq_domain *d = irq_find_matching_fwnode(acpi_gsi_domain_id, + DOMAIN_BUS_ANY); + + if (!d) + return NULL; + + return irq_domain_create_hierarchy(d, flags, size, fwnode, ops, + host_data); +} +EXPORT_SYMBOL_GPL(acpi_irq_create_hierarchy); diff --git a/drivers/acpi/nfit/Makefile b/drivers/acpi/nfit/Makefile index 751081c47886..07f53c4e85fe 100644 --- a/drivers/acpi/nfit/Makefile +++ b/drivers/acpi/nfit/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ACPI_NFIT) := nfit.o nfit-y := core.o nfit-y += intel.o diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index f1ed0befe303..23022cf20d26 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include <linux/list_sort.h> #include <linux/libnvdimm.h> diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c index d6c1b10f6c25..f0ae48515b48 100644 --- a/drivers/acpi/nfit/mce.c +++ b/drivers/acpi/nfit/mce.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * NFIT - Machine Check Handler * * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include <linux/notifier.h> #include <linux/acpi.h> diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index 2f8cf2a11e3b..6ee2b02af73e 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -1,16 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * NVDIMM Firmware Interface Table - NFIT * * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #ifndef __NFIT_H__ #define __NFIT_H__ diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 867f6e3f2b4f..eadbf90e65d1 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_numa.c - ACPI NUMA support * * Copyright (C) 2002 Takayoshi Kochi <t-kochi@bq.jp.nec.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * */ #define pr_fmt(fmt) "ACPI: " fmt @@ -339,7 +325,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) } static int __init -acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, +acpi_parse_x2apic_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_x2apic_cpu_affinity *processor_affinity; @@ -348,7 +334,7 @@ acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_x2apic_affinity_init(processor_affinity); @@ -357,7 +343,7 @@ acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, } static int __init -acpi_parse_processor_affinity(struct acpi_subtable_header *header, +acpi_parse_processor_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_cpu_affinity *processor_affinity; @@ -366,7 +352,7 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_processor_affinity_init(processor_affinity); @@ -375,7 +361,7 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, } static int __init -acpi_parse_gicc_affinity(struct acpi_subtable_header *header, +acpi_parse_gicc_affinity(union acpi_subtable_headers *header, const unsigned long end) { struct acpi_srat_gicc_affinity *processor_affinity; @@ -384,7 +370,7 @@ acpi_parse_gicc_affinity(struct acpi_subtable_header *header, if (!processor_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ acpi_numa_gicc_affinity_init(processor_affinity); @@ -395,7 +381,7 @@ acpi_parse_gicc_affinity(struct acpi_subtable_header *header, static int __initdata parsed_numa_memblks; static int __init -acpi_parse_memory_affinity(struct acpi_subtable_header * header, +acpi_parse_memory_affinity(union acpi_subtable_headers * header, const unsigned long end) { struct acpi_srat_mem_affinity *memory_affinity; @@ -404,7 +390,7 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, if (!memory_affinity) return -EINVAL; - acpi_table_print_srat_entry(header); + acpi_table_print_srat_entry(&header->common); /* let architecture-dependent part to do it */ if (!acpi_numa_memory_affinity_init(memory_affinity)) diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index 85287b8fe3aa..9f8712a557b3 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * nvs.c - Routines for saving and restoring ACPI NVS memory region * * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. - * - * This file is released under the GPLv2. */ #include <linux/io.h> diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c index efd2ce099893..bec0bebc7f52 100644 --- a/drivers/acpi/osi.c +++ b/drivers/acpi/osi.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * osi.c - _OSI implementation * * Copyright (C) 2016 Intel Corporation * Author: Lv Zheng <lv.zheng@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Uncomment next line to get verbose printout */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f29e427d0d1d..9c0edf2fc0dd 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_osl.c - OS-dependent functions ($Revision: 83 $) * @@ -6,21 +7,6 @@ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * Copyright (c) 2008 Intel Corporation * Author: Matthew Wilcox <willy@linux.intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * */ #include <linux/module.h> @@ -315,8 +301,8 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) * During early init (when acpi_permanent_mmap has not been set yet) this * routine simply calls __acpi_map_table() to get the job done. */ -void __iomem *__ref -acpi_os_map_iomem(acpi_physical_address phys, acpi_size size) +void __iomem __ref +*acpi_os_map_iomem(acpi_physical_address phys, acpi_size size) { struct acpi_ioremap *map; void __iomem *virt; diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index c576a6fe4ebb..d2549ae65e1b 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $) * @@ -6,20 +7,6 @@ * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de> * (c) Copyright 2008 Hewlett-Packard Development Company, L.P. * Bjorn Helgaas <bjorn.helgaas@hp.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index df70b1eaef58..db11f7771ef1 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $) * @@ -5,20 +6,6 @@ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de> * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * * TBD: * 1. Support more than one IRQ resource entry per link device (index). * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index a4e8432fc2fb..6b347d9920cc 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016 Broadcom * Author: Jayachandran C <jchandra@broadcom.com> * Copyright (C) 2016 Semihalf * Author: Tomasz Nowicki <tn@semihalf.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation (the "GPL"). - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 (GPLv2) for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 (GPLv2) along with this source code. */ #define pr_fmt(fmt) "ACPI: " fmt @@ -52,6 +41,18 @@ struct mcfg_fixup { static struct mcfg_fixup mcfg_quirks[] = { /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ +#define AL_ECAM(table_id, rev, seg, ops) \ + { "AMAZON", table_id, rev, seg, MCFG_BUS_ANY, ops } + + AL_ECAM("GRAVITON", 0, 0, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 1, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 2, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 3, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 4, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 5, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 6, &al_pcie_ops), + AL_ECAM("GRAVITON", 0, 7, &al_pcie_ops), + #define QCOM_ECAM32(seg) \ { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops } diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 707aafc7c2aa..39f5d172e84f 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 40 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> @@ -145,6 +132,7 @@ static struct pci_osc_bit_struct pci_osc_support_bit[] = { { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" }, { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" }, { OSC_PCI_MSI_SUPPORT, "MSI" }, + { OSC_PCI_HPX_TYPE_3_SUPPORT, "HPX-Type3" }, }; static struct pci_osc_bit_struct pci_osc_control_bit[] = { @@ -446,6 +434,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, * PCI domains, so we indicate this in _OSC support capabilities. */ support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; + support |= OSC_PCI_HPX_TYPE_3_SUPPORT; if (pci_ext_cfg_avail()) support |= OSC_PCI_EXT_CONFIG_SUPPORT; if (pcie_aspm_support_enabled()) diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index e90b61f7d2db..ca2461d1bf14 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * pci_slot.c - ACPI PCI Slot Driver * @@ -11,15 +12,6 @@ * * Copyright (C) 2013 Huawei Tech. Co., Ltd. * Jiang Liu <jiang.liu@huawei.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c index c14cfaea92e2..452041398b34 100644 --- a/drivers/acpi/pmic/intel_pmic.c +++ b/drivers/acpi/pmic/intel_pmic.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * intel_pmic.c - Intel PMIC operation region driver * * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/export.h> @@ -292,8 +284,6 @@ int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, intel_pmic_thermal_handler, NULL, opregion); if (ACPI_FAILURE(status)) { - acpi_remove_address_space_handler(handle, PMIC_POWER_OPREGION_ID, - intel_pmic_power_handler); ret = -ENODEV; goto out_remove_power_handler; } diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 665e93ca0b40..fe1e7bc91a5e 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * drivers/acpi/power.c - ACPI Power Resources management. * @@ -5,20 +6,6 @@ * Author: Andy Grover <andrew.grover@intel.com> * Author: Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* @@ -55,6 +42,11 @@ ACPI_MODULE_NAME("power"); #define ACPI_POWER_RESOURCE_STATE_ON 0x01 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF +struct acpi_power_dependent_device { + struct device *dev; + struct list_head node; +}; + struct acpi_power_resource { struct acpi_device device; struct list_head list_node; @@ -64,6 +56,7 @@ struct acpi_power_resource { unsigned int ref_count; bool wakeup_enabled; struct mutex resource_lock; + struct list_head dependents; }; struct acpi_power_resource_entry { @@ -245,8 +238,121 @@ static int acpi_power_get_list_state(struct list_head *list, int *state) return 0; } +static int +acpi_power_resource_add_dependent(struct acpi_power_resource *resource, + struct device *dev) +{ + struct acpi_power_dependent_device *dep; + int ret = 0; + + mutex_lock(&resource->resource_lock); + list_for_each_entry(dep, &resource->dependents, node) { + /* Only add it once */ + if (dep->dev == dev) + goto unlock; + } + + dep = kzalloc(sizeof(*dep), GFP_KERNEL); + if (!dep) { + ret = -ENOMEM; + goto unlock; + } + + dep->dev = dev; + list_add_tail(&dep->node, &resource->dependents); + dev_dbg(dev, "added power dependency to [%s]\n", resource->name); + +unlock: + mutex_unlock(&resource->resource_lock); + return ret; +} + +static void +acpi_power_resource_remove_dependent(struct acpi_power_resource *resource, + struct device *dev) +{ + struct acpi_power_dependent_device *dep; + + mutex_lock(&resource->resource_lock); + list_for_each_entry(dep, &resource->dependents, node) { + if (dep->dev == dev) { + list_del(&dep->node); + kfree(dep); + dev_dbg(dev, "removed power dependency to [%s]\n", + resource->name); + break; + } + } + mutex_unlock(&resource->resource_lock); +} + +/** + * acpi_device_power_add_dependent - Add dependent device of this ACPI device + * @adev: ACPI device pointer + * @dev: Dependent device + * + * If @adev has non-empty _PR0 the @dev is added as dependent device to all + * power resources returned by it. This means that whenever these power + * resources are turned _ON the dependent devices get runtime resumed. This + * is needed for devices such as PCI to allow its driver to re-initialize + * it after it went to D0uninitialized. + * + * If @adev does not have _PR0 this does nothing. + * + * Returns %0 in case of success and negative errno otherwise. + */ +int acpi_device_power_add_dependent(struct acpi_device *adev, + struct device *dev) +{ + struct acpi_power_resource_entry *entry; + struct list_head *resources; + int ret; + + if (!adev->flags.power_manageable) + return 0; + + resources = &adev->power.states[ACPI_STATE_D0].resources; + list_for_each_entry(entry, resources, node) { + ret = acpi_power_resource_add_dependent(entry->resource, dev); + if (ret) + goto err; + } + + return 0; + +err: + list_for_each_entry(entry, resources, node) + acpi_power_resource_remove_dependent(entry->resource, dev); + + return ret; +} + +/** + * acpi_device_power_remove_dependent - Remove dependent device + * @adev: ACPI device pointer + * @dev: Dependent device + * + * Does the opposite of acpi_device_power_add_dependent() and removes the + * dependent device if it is found. Can be called to @adev that does not + * have _PR0 as well. + */ +void acpi_device_power_remove_dependent(struct acpi_device *adev, + struct device *dev) +{ + struct acpi_power_resource_entry *entry; + struct list_head *resources; + + if (!adev->flags.power_manageable) + return; + + resources = &adev->power.states[ACPI_STATE_D0].resources; + list_for_each_entry_reverse(entry, resources, node) + acpi_power_resource_remove_dependent(entry->resource, dev); +} + static int __acpi_power_on(struct acpi_power_resource *resource) { + struct acpi_power_dependent_device *dep; acpi_status status = AE_OK; status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL); @@ -256,6 +362,21 @@ static int __acpi_power_on(struct acpi_power_resource *resource) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", resource->name)); + /* + * If there are other dependents on this power resource we need to + * resume them now so that their drivers can re-initialize the + * hardware properly after it went back to D0. + */ + if (list_empty(&resource->dependents) || + list_is_singular(&resource->dependents)) + return 0; + + list_for_each_entry(dep, &resource->dependents, node) { + dev_dbg(dep->dev, "runtime resuming because [%s] turned on\n", + resource->name); + pm_request_resume(dep->dev); + } + return 0; } @@ -535,12 +656,12 @@ int acpi_device_sleep_wake(struct acpi_device *dev, /* * Try to execute _DSW first. * - * Three agruments are needed for the _DSW object: + * Three arguments are needed for the _DSW object: * Argument 0: enable/disable the wake capabilities * Argument 1: target system state * Argument 2: target device state * When _DSW object is called to disable the wake capabilities, maybe - * the first argument is filled. The values of the other two agruments + * the first argument is filled. The values of the other two arguments * are meaningless. */ in_arg[0].type = ACPI_TYPE_INTEGER; @@ -823,6 +944,7 @@ int acpi_add_power_resource(acpi_handle handle) ACPI_STA_DEFAULT); mutex_init(&resource->resource_lock); INIT_LIST_HEAD(&resource->list_node); + INIT_LIST_HEAD(&resource->dependents); resource->name = device->pnp.bus_id; strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_POWER_CLASS); diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 065c4fc245d1..1e7ac0bd0d3a 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -164,7 +164,7 @@ static struct acpi_pptt_cache *acpi_find_cache_level(struct acpi_table_header *t } /** - * acpi_count_levels() - Given a PPTT table, and a cpu node, count the caches + * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches * @table_hdr: Pointer to the head of the PPTT table * @cpu_node: processor node we wish to count caches for * @@ -235,7 +235,7 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr, /** * acpi_find_processor_node() - Given a PPTT table find the requested processor * @table_hdr: Pointer to the head of the PPTT table - * @acpi_cpu_id: cpu we are searching for + * @acpi_cpu_id: CPU we are searching for * * Find the subtable entry describing the provided processor. * This is done by iterating the PPTT table looking for processor nodes @@ -432,17 +432,40 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table, } } +static bool flag_identical(struct acpi_table_header *table_hdr, + struct acpi_pptt_processor *cpu) +{ + struct acpi_pptt_processor *next; + + /* heterogeneous machines must use PPTT revision > 1 */ + if (table_hdr->revision < 2) + return false; + + /* Locate the last node in the tree with IDENTICAL set */ + if (cpu->flags & ACPI_PPTT_ACPI_IDENTICAL) { + next = fetch_pptt_node(table_hdr, cpu->parent); + if (!(next && next->flags & ACPI_PPTT_ACPI_IDENTICAL)) + return true; + } + + return false; +} + /* Passing level values greater than this will result in search termination */ #define PPTT_ABORT_PACKAGE 0xFF -static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_table_header *table_hdr, - struct acpi_pptt_processor *cpu, - int level, int flag) +static struct acpi_pptt_processor *acpi_find_processor_tag(struct acpi_table_header *table_hdr, + struct acpi_pptt_processor *cpu, + int level, int flag) { struct acpi_pptt_processor *prev_node; while (cpu && level) { - if (cpu->flags & flag) + /* special case the identical flag to find last identical */ + if (flag == ACPI_PPTT_ACPI_IDENTICAL) { + if (flag_identical(table_hdr, cpu)) + break; + } else if (cpu->flags & flag) break; pr_debug("level %d\n", level); prev_node = fetch_pptt_node(table_hdr, cpu->parent); @@ -456,21 +479,21 @@ static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_ta static void acpi_pptt_warn_missing(void) { - pr_warn_once("No PPTT table found, cpu and cache topology may be inaccurate\n"); + pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n"); } /** * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature * @table: Pointer to the head of the PPTT table - * @cpu: Kernel logical cpu number + * @cpu: Kernel logical CPU number * @level: A level that terminates the search * @flag: A flag which terminates the search * - * Get a unique value given a cpu, and a topology level, that can be + * Get a unique value given a CPU, and a topology level, that can be * matched to determine which cpus share common topological features * at that level. * - * Return: Unique value, or -ENOENT if unable to locate cpu + * Return: Unique value, or -ENOENT if unable to locate CPU */ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, unsigned int cpu, int level, int flag) @@ -480,8 +503,8 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, cpu_node = acpi_find_processor_node(table, acpi_cpu_id); if (cpu_node) { - cpu_node = acpi_find_processor_package_id(table, cpu_node, - level, flag); + cpu_node = acpi_find_processor_tag(table, cpu_node, + level, flag); /* * As per specification if the processor structure represents * an actual processor, then ACPI processor ID must be valid. @@ -510,7 +533,7 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag) return -ENOENT; } retval = topology_get_acpi_cpu_tag(table, cpu, level, flag); - pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n", + pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n", cpu, level, retval); acpi_put_table(table); @@ -519,9 +542,9 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag) /** * acpi_find_last_cache_level() - Determines the number of cache levels for a PE - * @cpu: Kernel logical cpu number + * @cpu: Kernel logical CPU number * - * Given a logical cpu number, returns the number of levels of cache represented + * Given a logical CPU number, returns the number of levels of cache represented * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0 * indicating we didn't find any cache levels. * @@ -534,7 +557,7 @@ int acpi_find_last_cache_level(unsigned int cpu) int number_of_levels = 0; acpi_status status; - pr_debug("Cache Setup find last level cpu=%d\n", cpu); + pr_debug("Cache Setup find last level CPU=%d\n", cpu); acpi_cpu_id = get_acpi_id_for_cpu(cpu); status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); @@ -551,14 +574,14 @@ int acpi_find_last_cache_level(unsigned int cpu) /** * cache_setup_acpi() - Override CPU cache topology with data from the PPTT - * @cpu: Kernel logical cpu number + * @cpu: Kernel logical CPU number * * Updates the global cache info provided by cpu_get_cacheinfo() * when there are valid properties in the acpi_pptt_cache nodes. A * successful parse may not result in any updates if none of the - * cache levels have any valid flags set. Futher, a unique value is + * cache levels have any valid flags set. Further, a unique value is * associated with each known CPU cache entry. This unique value - * can be used to determine whether caches are shared between cpus. + * can be used to determine whether caches are shared between CPUs. * * Return: -ENOENT on failure to find table, or 0 on success */ @@ -567,7 +590,7 @@ int cache_setup_acpi(unsigned int cpu) struct acpi_table_header *table; acpi_status status; - pr_debug("Cache Setup ACPI cpu %d\n", cpu); + pr_debug("Cache Setup ACPI CPU %d\n", cpu); status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); if (ACPI_FAILURE(status)) { @@ -582,8 +605,8 @@ int cache_setup_acpi(unsigned int cpu) } /** - * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu - * @cpu: Kernel logical cpu number + * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU + * @cpu: Kernel logical CPU number * @level: The topological level for which we would like a unique ID * * Determine a topology unique ID for each thread/core/cluster/mc_grouping @@ -596,7 +619,7 @@ int cache_setup_acpi(unsigned int cpu) * other levels beyond this use a generated value to uniquely identify * a topological feature. * - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. * Otherwise returns a value which represents a unique topological feature. */ int find_acpi_cpu_topology(unsigned int cpu, int level) @@ -606,12 +629,12 @@ int find_acpi_cpu_topology(unsigned int cpu, int level) /** * find_acpi_cpu_cache_topology() - Determine a unique cache topology value - * @cpu: Kernel logical cpu number + * @cpu: Kernel logical CPU number * @level: The cache level for which we would like a unique ID * * Determine a unique ID for each unified cache in the system * - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. * Otherwise returns a value which represents a unique topological feature. */ int find_acpi_cpu_cache_topology(unsigned int cpu, int level) @@ -643,20 +666,46 @@ int find_acpi_cpu_cache_topology(unsigned int cpu, int level) /** - * find_acpi_cpu_topology_package() - Determine a unique cpu package value - * @cpu: Kernel logical cpu number + * find_acpi_cpu_topology_package() - Determine a unique CPU package value + * @cpu: Kernel logical CPU number * - * Determine a topology unique package ID for the given cpu. + * Determine a topology unique package ID for the given CPU. * This ID can then be used to group peers, which will have matching ids. * * The search terminates when either a level is found with the PHYSICAL_PACKAGE * flag set or we reach a root node. * - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. - * Otherwise returns a value which represents the package for this cpu. + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. + * Otherwise returns a value which represents the package for this CPU. */ int find_acpi_cpu_topology_package(unsigned int cpu) { return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, ACPI_PPTT_PHYSICAL_PACKAGE); } + +/** + * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag + * @cpu: Kernel logical CPU number + * + * Determine a unique heterogeneous tag for the given CPU. CPUs with the same + * implementation should have matching tags. + * + * The returned tag can be used to group peers with identical implementation. + * + * The search terminates when a level is found with the identical implementation + * flag set or we reach a root node. + * + * Due to limitations in the PPTT data structure, there may be rare situations + * where two cores in a heterogeneous machine may be identical, but won't have + * the same tag. + * + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. + * Otherwise returns a value which represents a group of identical cores + * similar to this CPU. + */ +int find_acpi_cpu_topology_hetero_id(unsigned int cpu) +{ + return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, + ACPI_PPTT_ACPI_IDENTICAL); +} diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 8c0a54d50d0e..f32beb7d7882 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2005 Intel Corporation * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9d6aff22684e..aea8d674a33d 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_driver.c - ACPI Processor Driver * @@ -8,20 +9,6 @@ * - Added processor hotplug support * Copyright (C) 2013, Intel Corporation * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 98d4ec5bf450..ed56c6d20b08 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_idle - idle state submodule to the ACPI processor driver * @@ -8,20 +9,6 @@ * - Added processor hotplug support * Copyright (C) 2005 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> * - Added support for C3 on SMP - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define pr_fmt(fmt) "ACPI: " fmt @@ -209,6 +196,7 @@ static void tsc_check_state(int state) case X86_VENDOR_AMD: case X86_VENDOR_INTEL: case X86_VENDOR_CENTAUR: + case X86_VENDOR_ZHAOXIN: /* * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index a303fd0e108c..ee87cb6f6e59 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $) * @@ -6,20 +7,6 @@ * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> * - Added processor hotplug support - * - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * */ #include <linux/kernel.h> @@ -181,7 +168,7 @@ void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) acpi_processor_ppc_ost(pr->handle, 0); } if (ret >= 0) - cpufreq_update_policy(pr->id); + cpufreq_update_limits(pr->id); } int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 59c3a5d1e600..50fb0107375e 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_thermal.c - Passive cooling submodule of the ACPI processor driver * @@ -6,20 +7,6 @@ * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> * - Added processor hotplug support - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index fbc936cf2025..532a1ae3595a 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_throttling.c - Throttling submodule of the ACPI processor driver * @@ -6,20 +7,6 @@ * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> * - Added processor hotplug support - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 77abe0ec4043..ea3d700da3ca 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ACPI device specific properties support. * @@ -7,10 +8,6 @@ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> * Darren Hart <dvhart@linux.intel.com> * Rafael J. Wysocki <rafael.j.wysocki@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> @@ -44,6 +41,7 @@ static const guid_t prp_guids[] = { 0xbf, 0xf0, 0x76, 0x14, 0x38, 0x07, 0xc3, 0x89), }; +/* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */ static const guid_t ads_guid = GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6, 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b); @@ -602,15 +600,29 @@ static struct fwnode_handle * acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, const char *childname) { + char name[ACPI_PATH_SEGMENT_LENGTH]; struct fwnode_handle *child; + struct acpi_buffer path; + acpi_status status; - /* - * Find first matching named child node of this fwnode. - * For ACPI this will be a data only sub-node. - */ - fwnode_for_each_child_node(fwnode, child) - if (acpi_data_node_match(child, childname)) + path.length = sizeof(name); + path.pointer = name; + + fwnode_for_each_child_node(fwnode, child) { + if (is_acpi_data_node(child)) { + if (acpi_data_node_match(child, childname)) + return child; + continue; + } + + status = acpi_get_name(ACPI_HANDLE_FWNODE(child), + ACPI_SINGLE_NAME, &path); + if (ACPI_FAILURE(status)) + break; + + if (!strncmp(name, childname, ACPI_NAMESEG_SIZE)) return child; + } return NULL; } @@ -1031,6 +1043,14 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, const struct acpi_data_node *data = to_acpi_data_node(fwnode); struct acpi_data_node *dn; + /* + * We can have a combination of device and data nodes, e.g. with + * hierarchical _DSD properties. Make sure the adev pointer is + * restored before going through data nodes, otherwise we will + * be looking for data_nodes below the last device found instead + * of the common fwnode shared by device_nodes and data_nodes. + */ + adev = to_acpi_device_node(fwnode); if (adev) head = &adev->data.subnodes; else if (data) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index d556f2144de8..2a3e392751e0 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/acpi/resource.c - ACPI device resources interpretation. * @@ -6,15 +7,6 @@ * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 96c5e27967f4..6e88224f60f0 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -1,23 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $) * * Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de> * Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com> * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/init.h> diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 5008ead4609a..87b74e9015e5 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * SMBus driver for ACPI Embedded Controller (v0.1) * * Copyright (c) 2007 Alexey Starikovskiy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2. */ #include <linux/acpi.h> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 446c959a8f08..0e28270b0fd8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * scan.c - support for transforming the ACPI namespace into individual objects */ @@ -763,18 +764,16 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) } EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); -static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, - struct acpi_device_wakeup *wakeup) +static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev) { + acpi_handle handle = dev->handle; + struct acpi_device_wakeup *wakeup = &dev->wakeup; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *package = NULL; union acpi_object *element = NULL; acpi_status status; int err = -ENODATA; - if (!wakeup) - return -EINVAL; - INIT_LIST_HEAD(&wakeup->resources); /* _PRW */ @@ -848,9 +847,9 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, static bool acpi_wakeup_gpe_init(struct acpi_device *device) { static const struct acpi_device_id button_device_ids[] = { - {"PNP0C0C", 0}, - {"PNP0C0D", 0}, - {"PNP0C0E", 0}, + {"PNP0C0C", 0}, /* Power button */ + {"PNP0C0D", 0}, /* Lid */ + {"PNP0C0E", 0}, /* Sleep button */ {"", 0}, }; struct acpi_device_wakeup *wakeup = &device->wakeup; @@ -883,8 +882,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) if (!acpi_has_method(device->handle, "_PRW")) return; - err = acpi_bus_extract_wakeup_device_power_package(device->handle, - &device->wakeup); + err = acpi_bus_extract_wakeup_device_power_package(device); if (err) { dev_err(&device->dev, "_PRW evaluation error: %d\n", err); return; @@ -895,7 +893,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) /* * Call _PSW/_DSW object to disable its ability to wake the sleeping * system for the ACPI device with the _PRW object. - * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. + * The _PSW object is deprecated in ACPI 3.0 and is replaced by _DSW. * So it is necessary to call _DSW object first. Only when it is not * present will the _PSW object used. */ @@ -2241,10 +2239,10 @@ static struct acpi_probe_entry *ape; static int acpi_probe_count; static DEFINE_MUTEX(acpi_probe_mutex); -static int __init acpi_match_madt(struct acpi_subtable_header *header, +static int __init acpi_match_madt(union acpi_subtable_headers *header, const unsigned long end) { - if (!ape->subtable_valid || ape->subtable_valid(header, ape)) + if (!ape->subtable_valid || ape->subtable_valid(&header->common, ape)) if (!ape->probe_subtbl(header, end)) acpi_probe_count++; @@ -2260,7 +2258,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr) mutex_lock(&acpi_probe_mutex); for (ape = ap_head; nr; ape++, nr--) { - if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) { + if (ACPI_COMPARE_NAMESEG(ACPI_SIG_MADT, ape->id)) { acpi_probe_count = 0; acpi_table_parse_madt(ape->type, acpi_match_madt, 0); count += acpi_probe_count; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 403c4ff15349..f0fe7c15d657 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * sleep.c - ACPI sleep support. * @@ -5,9 +6,6 @@ * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com> * Copyright (c) 2000-2003 Patrick Mochel * Copyright (c) 2003 Open Source Development Lab - * - * This file is released under the GPLv2. - * */ #include <linux/delay.h> @@ -79,7 +77,7 @@ static int acpi_sleep_prepare(u32 acpi_state) return 0; } -static bool acpi_sleep_state_supported(u8 sleep_state) +bool acpi_sleep_state_supported(u8 sleep_state) { acpi_status status; u8 type_a, type_b; @@ -454,14 +452,6 @@ static int acpi_pm_prepare(void) return error; } -static int find_powerf_dev(struct device *dev, void *data) -{ - struct acpi_device *device = to_acpi_device(dev); - const char *hid = acpi_device_hid(device); - - return !strcmp(hid, ACPI_BUTTON_HID_POWERF); -} - /** * acpi_pm_finish - Instruct the platform to leave a sleep state. * @@ -470,7 +460,7 @@ static int find_powerf_dev(struct device *dev, void *data) */ static void acpi_pm_finish(void) { - struct device *pwr_btn_dev; + struct acpi_device *pwr_btn_adev; u32 acpi_state = acpi_target_sleep_state; acpi_ec_unblock_transactions(); @@ -501,11 +491,11 @@ static void acpi_pm_finish(void) return; pwr_btn_event_pending = false; - pwr_btn_dev = bus_find_device(&acpi_bus_type, NULL, NULL, - find_powerf_dev); - if (pwr_btn_dev) { - pm_wakeup_event(pwr_btn_dev, 0); - put_device(pwr_btn_dev); + pwr_btn_adev = acpi_dev_get_first_match_dev(ACPI_BUTTON_HID_POWERF, + NULL, -1); + if (pwr_btn_adev) { + pm_wakeup_event(&pwr_btn_adev->dev, 0); + acpi_dev_put(pwr_btn_adev); } } @@ -977,6 +967,8 @@ static int acpi_s2idle_prepare(void) if (acpi_sci_irq_valid()) enable_irq_wake(acpi_sci_irq); + acpi_enable_wakeup_devices(ACPI_STATE_S0); + /* Change the configuration of GPEs to avoid spurious wakeup. */ acpi_enable_all_wakeup_gpes(); acpi_os_wait_events_complete(); @@ -1027,6 +1019,8 @@ static void acpi_s2idle_restore(void) { acpi_enable_all_runtime_gpes(); + acpi_disable_wakeup_devices(ACPI_STATE_S0); + if (acpi_sci_irq_valid()) disable_irq_wake(acpi_sci_irq); @@ -1128,15 +1122,19 @@ void __init acpi_no_s4_hw_signature(void) nosigcheck = true; } -static int acpi_hibernation_begin(void) +static int acpi_hibernation_begin(pm_message_t stage) { - int error; + if (!nvs_nosave) { + int error = suspend_nvs_alloc(); + if (error) + return error; + } - error = nvs_nosave ? 0 : suspend_nvs_alloc(); - if (!error) - acpi_pm_start(ACPI_STATE_S4); + if (stage.event == PM_EVENT_HIBERNATE) + pm_set_suspend_via_firmware(); - return error; + acpi_pm_start(ACPI_STATE_S4); + return 0; } static int acpi_hibernation_enter(void) @@ -1196,7 +1194,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops = { * function is used if the pre-ACPI 2.0 suspend ordering has been * requested. */ -static int acpi_hibernation_begin_old(void) +static int acpi_hibernation_begin_old(pm_message_t stage) { int error; /* @@ -1207,16 +1205,21 @@ static int acpi_hibernation_begin_old(void) acpi_sleep_tts_switch(ACPI_STATE_S4); error = acpi_sleep_prepare(ACPI_STATE_S4); + if (error) + return error; - if (!error) { - if (!nvs_nosave) - error = suspend_nvs_alloc(); - if (!error) { - acpi_target_sleep_state = ACPI_STATE_S4; - acpi_scan_lock_acquire(); - } + if (!nvs_nosave) { + error = suspend_nvs_alloc(); + if (error) + return error; } - return error; + + if (stage.event == PM_EVENT_HIBERNATE) + pm_set_suspend_via_firmware(); + + acpi_target_sleep_state = ACPI_STATE_S4; + acpi_scan_lock_acquire(); + return 0; } /* diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index c336784d0bcb..d73b4535e79d 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012, Intel Corporation * Copyright (c) 2015, Red Hat, Inc. * Copyright (c) 2015, 2016 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * */ #define pr_fmt(fmt) "ACPI: SPCR: " fmt @@ -28,7 +24,7 @@ EXPORT_SYMBOL(qdf2400_e44_present); /* * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit. - * Detect them by examining the OEM fields in the SPCR header, similiar to PCI + * Detect them by examining the OEM fields in the SPCR header, similar to PCI * quirk detection in pci_mcfg.c. */ static bool qdf2400_erratum_44_present(struct acpi_table_header *h) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index fa76f5e41b5c..75948a3f1a20 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -327,9 +327,9 @@ static struct kobject *hotplug_kobj; struct acpi_table_attr { struct bin_attribute attr; - char name[ACPI_NAME_SIZE]; + char name[ACPI_NAMESEG_SIZE]; int instance; - char filename[ACPI_NAME_SIZE+ACPI_INST_SIZE]; + char filename[ACPI_NAMESEG_SIZE+ACPI_INST_SIZE]; struct list_head node; }; @@ -368,10 +368,10 @@ static int acpi_table_attr_init(struct kobject *tables_obj, char instance_str[ACPI_INST_SIZE]; sysfs_attr_init(&table_attr->attr.attr); - ACPI_MOVE_NAME(table_attr->name, table_header->signature); + ACPI_COPY_NAMESEG(table_attr->name, table_header->signature); list_for_each_entry(attr, &acpi_table_attr_list, node) { - if (ACPI_COMPARE_NAME(table_attr->name, attr->name)) + if (ACPI_COMPARE_NAMESEG(table_attr->name, attr->name)) if (table_attr->instance < attr->instance) table_attr->instance = attr->instance; } @@ -382,8 +382,8 @@ static int acpi_table_attr_init(struct kobject *tables_obj, return -ERANGE; } - ACPI_MOVE_NAME(table_attr->filename, table_header->signature); - table_attr->filename[ACPI_NAME_SIZE] = '\0'; + ACPI_COPY_NAMESEG(table_attr->filename, table_header->signature); + table_attr->filename[ACPI_NAMESEG_SIZE] = '\0'; if (table_attr->instance > 1 || (table_attr->instance == 1 && !acpi_get_table (table_header->signature, 2, &header))) { @@ -484,7 +484,7 @@ static int acpi_table_data_init(struct acpi_table_header *th) int i; for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) { - if (ACPI_COMPARE_NAME(th->signature, acpi_data_objs[i].name)) { + if (ACPI_COMPARE_NAMESEG(th->signature, acpi_data_objs[i].name)) { data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL); if (!data_attr) return -ENOMEM; diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8fccbe49612a..b32327759380 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_tables.c - ACPI Boot-Time Table Parsing * * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * */ /* Uncomment next line to get verbose printout */ @@ -49,6 +35,16 @@ static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; static int acpi_apic_instance __initdata; +enum acpi_subtable_type { + ACPI_SUBTABLE_COMMON, + ACPI_SUBTABLE_HMAT, +}; + +struct acpi_subtable_entry { + union acpi_subtable_headers *hdr; + enum acpi_subtable_type type; +}; + /* * Disable table checksum verification for the early stage due to the size * limitation of the current x86 early mapping implementation. @@ -217,6 +213,50 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } +static unsigned long __init +acpi_get_entry_type(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.type; + case ACPI_SUBTABLE_HMAT: + return entry->hdr->hmat.type; + } + return 0; +} + +static unsigned long __init +acpi_get_entry_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return entry->hdr->common.length; + case ACPI_SUBTABLE_HMAT: + return entry->hdr->hmat.length; + } + return 0; +} + +static unsigned long __init +acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) +{ + switch (entry->type) { + case ACPI_SUBTABLE_COMMON: + return sizeof(entry->hdr->common); + case ACPI_SUBTABLE_HMAT: + return sizeof(entry->hdr->hmat); + } + return 0; +} + +static enum acpi_subtable_type __init +acpi_get_subtable_type(char *id) +{ + if (strncmp(id, ACPI_SIG_HMAT, 4) == 0) + return ACPI_SUBTABLE_HMAT; + return ACPI_SUBTABLE_COMMON; +} + /** * acpi_parse_entries_array - for each proc_num find a suitable subtable * @@ -240,14 +280,13 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) * On success returns sum of all matching entries for all proc handlers. * Otherwise, -ENODEV or -EINVAL is returned. */ -static int __init -acpi_parse_entries_array(char *id, unsigned long table_size, +static int __init acpi_parse_entries_array(char *id, unsigned long table_size, struct acpi_table_header *table_header, struct acpi_subtable_proc *proc, int proc_num, unsigned int max_entries) { - struct acpi_subtable_header *entry; - unsigned long table_end; + struct acpi_subtable_entry entry; + unsigned long table_end, subtable_len, entry_len; int count = 0; int errs = 0; int i; @@ -270,19 +309,20 @@ acpi_parse_entries_array(char *id, unsigned long table_size, /* Parse all entries looking for a match. */ - entry = (struct acpi_subtable_header *) + entry.type = acpi_get_subtable_type(id); + entry.hdr = (union acpi_subtable_headers *) ((unsigned long)table_header + table_size); + subtable_len = acpi_get_subtable_header_length(&entry); - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + while (((unsigned long)entry.hdr) + subtable_len < table_end) { if (max_entries && count >= max_entries) break; for (i = 0; i < proc_num; i++) { - if (entry->type != proc[i].id) + if (acpi_get_entry_type(&entry) != proc[i].id) continue; if (!proc[i].handler || - (!errs && proc[i].handler(entry, table_end))) { + (!errs && proc[i].handler(entry.hdr, table_end))) { errs++; continue; } @@ -297,13 +337,14 @@ acpi_parse_entries_array(char *id, unsigned long table_size, * If entry->length is 0, break from this loop to avoid * infinite loop. */ - if (entry->length == 0) { + entry_len = acpi_get_entry_length(&entry); + if (entry_len == 0) { pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id); return -EINVAL; } - entry = (struct acpi_subtable_header *) - ((unsigned long)entry + entry->length); + entry.hdr = (union acpi_subtable_headers *) + ((unsigned long)entry.hdr + entry_len); } if (max_entries && count > max_entries) { @@ -314,8 +355,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size, return errs ? -EINVAL : count; } -int __init -acpi_table_parse_entries_array(char *id, +int __init acpi_table_parse_entries_array(char *id, unsigned long table_size, struct acpi_subtable_proc *proc, int proc_num, unsigned int max_entries) @@ -346,8 +386,7 @@ acpi_table_parse_entries_array(char *id, return count; } -int __init -acpi_table_parse_entries(char *id, +int __init acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_tbl_entry_handler handler, @@ -362,8 +401,7 @@ acpi_table_parse_entries(char *id, max_entries); } -int __init -acpi_table_parse_madt(enum acpi_madt_type id, +int __init acpi_table_parse_madt(enum acpi_madt_type id, acpi_tbl_entry_handler handler, unsigned int max_entries) { return acpi_table_parse_entries(ACPI_SIG_MADT, @@ -452,16 +490,17 @@ static u8 __init acpi_table_checksum(u8 *buffer, u32 length) /* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */ static const char * const table_sigs[] = { - ACPI_SIG_BERT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, ACPI_SIG_EINJ, - ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, ACPI_SIG_MSCT, - ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, ACPI_SIG_ASF, - ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, ACPI_SIG_HPET, - ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, ACPI_SIG_MCHI, - ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA, - ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT, - ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, - ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_IORT, - ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT, NULL }; + ACPI_SIG_BERT, ACPI_SIG_BGRT, ACPI_SIG_CPEP, ACPI_SIG_ECDT, + ACPI_SIG_EINJ, ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT, + ACPI_SIG_MSCT, ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT, + ACPI_SIG_ASF, ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR, + ACPI_SIG_HPET, ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG, + ACPI_SIG_MCHI, ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, + ACPI_SIG_TCPA, ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, + ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, + ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, + ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT, + NULL }; #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) @@ -670,8 +709,8 @@ static void __init acpi_table_initrd_scan(void) table_length = table->length; /* Skip RSDT/XSDT which should only be used for override */ - if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) || - ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) { + if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_RSDT) || + ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_XSDT)) { acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); goto next_table; } @@ -725,8 +764,7 @@ static void *amlcode __attribute__ ((weakref("AmlCode"))); static void *dsdt_amlcode __attribute__ ((weakref("dsdt_aml_code"))); #endif -acpi_status -acpi_os_table_override(struct acpi_table_header *existing_table, +acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, struct acpi_table_header **new_table) { if (!existing_table || !new_table) @@ -788,7 +826,6 @@ static int __init acpi_parse_apic_instance(char *str) return 0; } - early_param("acpi_apic_instance", acpi_parse_apic_instance); static int __init acpi_force_table_verification_setup(char *s) @@ -797,7 +834,6 @@ static int __init acpi_force_table_verification_setup(char *s) return 0; } - early_param("acpi_force_table_verification", acpi_force_table_verification_setup); static int __init acpi_force_32bit_fadt_addr(char *s) @@ -807,5 +843,4 @@ static int __init acpi_force_32bit_fadt_addr(char *s) return 0; } - early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 551b71a24b85..00f12a86ecbd 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1,30 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * * This driver fully implements the ACPI thermal policy as described in the * ACPI 2.0 Specification. * * TBD: 1. Implement passive cooling hysteresis. * 2. Enhance passive cooling (CPU) states/limit interface to support * concepts of 'multiple limiters', upper/lower limits, etc. - * */ #include <linux/kernel.h> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index c4b06cc075f9..e3974a8f8fd4 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> @@ -738,16 +725,15 @@ bool acpi_dev_found(const char *hid) EXPORT_SYMBOL(acpi_dev_found); struct acpi_dev_match_info { - const char *dev_name; struct acpi_device_id hid[2]; const char *uid; s64 hrv; }; -static int acpi_dev_match_cb(struct device *dev, void *data) +static int acpi_dev_match_cb(struct device *dev, const void *data) { struct acpi_device *adev = to_acpi_device(dev); - struct acpi_dev_match_info *match = data; + const struct acpi_dev_match_info *match = data; unsigned long long hrv; acpi_status status; @@ -758,8 +744,6 @@ static int acpi_dev_match_cb(struct device *dev, void *data) strcmp(adev->pnp.unique_id, match->uid))) return 0; - match->dev_name = acpi_dev_name(adev); - if (match->hrv == -1) return 1; @@ -806,18 +790,20 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) EXPORT_SYMBOL(acpi_dev_present); /** - * acpi_dev_get_first_match_name - Return name of first match of ACPI device + * acpi_dev_get_first_match_dev - Return the first match of ACPI device * @hid: Hardware ID of the device. * @uid: Unique ID of the device, pass NULL to not check _UID * @hrv: Hardware Revision of the device, pass -1 to not check _HRV * - * Return device name if a matching device was present + * Return the first match of ACPI device if a matching device was present * at the moment of invocation, or NULL otherwise. * + * The caller is responsible to call put_device() on the returned device. + * * See additional information in acpi_dev_present() as well. */ -const char * -acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) +struct acpi_device * +acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv) { struct acpi_dev_match_info match = {}; struct device *dev; @@ -827,9 +813,9 @@ acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) match.hrv = hrv; dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); - return dev ? match.dev_name : NULL; + return dev ? to_acpi_device(dev) : NULL; } -EXPORT_SYMBOL(acpi_dev_get_first_match_name); +EXPORT_SYMBOL(acpi_dev_get_first_match_dev); /* * acpi_backlight= handling, this is done here rather then in video_detect.c diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 43587ac680e4..31014c7d3793 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -112,7 +112,7 @@ static int video_detect_force_none(const struct dmi_system_id *d) static const struct dmi_system_id video_detect_dmi_table[] = { /* On Samsung X360, the BIOS will set a flag (VDRV) if generic * ACPI backlight device is used. This flag will definitively break - * the backlight interface (even the vendor interface) untill next + * the backlight interface (even the vendor interface) until next * reboot. It's why we should prevent video.ko from being used here * and we can't rely on a later call to acpi_video_unregister(). */ @@ -141,6 +141,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), }, }, + { + .callback = video_detect_force_vendor, + .ident = "Sony VPCEH3U1E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), + }, + }, /* * These models have a working acpi_video backlight control, and using diff --git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86/apple.c index b7c98ff82d78..c285c91a5e9c 100644 --- a/drivers/acpi/x86/apple.c +++ b/drivers/acpi/x86/apple.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * apple.c - Apple ACPI quirks * Copyright (C) 2017 Lukas Wunner <lukas@wunner.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License (version 2) as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index c6df14802741..ba277cd5c7fa 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * X86 ACPI Utility Functions * @@ -5,10 +6,6 @@ * * Based on various non upstream patches to support the CHT Whiskey Cove PMIC: * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> |