diff options
Diffstat (limited to 'drivers/acpi')
247 files changed, 4161 insertions, 1530 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 5b1938f4b626..f505e9a01b2d 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -79,7 +79,17 @@ config ACPI_DEBUGGER_USER endif config ACPI_SPCR_TABLE + bool "ACPI Serial Port Console Redirection Support" + default y if X86 + help + Enable support for Serial Port Console Redirection (SPCR) Table. + This table provides information about the configuration of the + earlycon console. + +config ACPI_LPIT bool + depends on X86_64 + default y config ACPI_SLEEP bool @@ -356,22 +366,6 @@ config ACPI_PCI_SLOT i.e., segment/bus/device/function tuples, with physical slots in the system. If you are unsure, say N. -config X86_PM_TIMER - bool "Power Management Timer Support" if EXPERT - depends on X86 - default y - help - The Power Management Timer is available on all ACPI-capable, - in most cases even if ACPI is unusable or blacklisted. - - This timing source is not affected by power management features - like aggressive processor idling, throttling, frequency and/or - voltage scaling, unlike the commonly used Time Stamp Counter - (TSC) timing source. - - You should nearly always say Y here because many modern - systems require this timer. - config ACPI_CONTAINER bool "Container and Module Devices" default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU) @@ -522,6 +516,12 @@ config CHT_WC_PMIC_OPREGION help This config adds ACPI operation region support for CHT Whiskey Cove PMIC. +config CHT_DC_TI_PMIC_OPREGION + bool "ACPI operation region support for Dollar Cove TI PMIC" + depends on INTEL_SOC_PMIC_CHTDC_TI + help + This config adds ACPI operation region support for Dollar Cove TI PMIC. + endif config ACPI_CONFIGFS @@ -536,4 +536,36 @@ if ARM64 source "drivers/acpi/arm64/Kconfig" endif +config TPS68470_PMIC_OPREGION + bool "ACPI operation region support for TPS68470 PMIC" + depends on MFD_TPS68470 + help + This config adds ACPI operation region support for TI TPS68470 PMIC. + TPS68470 device is an advanced power management unit that powers + a Compact Camera Module (CCM), generates clocks for image sensors, + drives a dual LED for flash and incorporates two LED drivers for + general purpose indicators. + This driver enables ACPI operation region support control voltage + regulators and clocks. + + This option is a bool as it provides an ACPI operation + region, which must be available before any of the devices + using this, are probed. + endif # ACPI + +config X86_PM_TIMER + bool "Power Management Timer Support" if EXPERT + depends on X86 && (ACPI || JAILHOUSE_GUEST) + default y + help + The Power Management Timer is available on all ACPI-capable, + in most cases even if ACPI is unusable or blacklisted. + + This timing source is not affected by power management features + like aggressive processor idling, throttling, frequency and/or + voltage scaling, unlike the commonly used Time Stamp Counter + (TSC) timing source. + + You should nearly always say Y here because many modern + systems require this timer. diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index cd1abc9bc325..41954a601989 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -57,6 +57,7 @@ acpi-$(CONFIG_DEBUG_FS) += debugfs.o acpi-$(CONFIG_ACPI_NUMA) += numa.o acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o acpi-y += acpi_lpat.o +acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o @@ -105,9 +106,12 @@ obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o obj-$(CONFIG_BXT_WC_PMIC_OPREGION) += pmic/intel_pmic_bxtwc.o obj-$(CONFIG_CHT_WC_PMIC_OPREGION) += pmic/intel_pmic_chtwc.o +obj-$(CONFIG_CHT_DC_TI_PMIC_OPREGION) += pmic/intel_pmic_chtdc_ti.o obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o +obj-$(CONFIG_TPS68470_PMIC_OPREGION) += pmic/tps68470_pmic.o + video-objs += acpi_video.o video_detect.o obj-y += dptf/ diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 8f52483219ba..47a7ed557bd6 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -265,6 +265,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); + /* fall through */ case ACPI_AC_NOTIFY_STATUS: case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index d5999eb41c00..d553b0087947 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -116,6 +116,10 @@ static const struct apd_device_desc hip08_i2c_desc = { .setup = acpi_apd_setup, .fixed_clk_rate = 250000000, }; +static const struct apd_device_desc thunderx2_i2c_desc = { + .setup = acpi_apd_setup, + .fixed_clk_rate = 125000000, +}; #endif #else @@ -180,6 +184,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { { "APMC0D0F", APD_ADDR(xgene_i2c_desc) }, { "BRCM900D", APD_ADDR(vulcan_spi_desc) }, { "CAV900D", APD_ADDR(vulcan_spi_desc) }, + { "CAV9007", APD_ADDR(thunderx2_i2c_desc) }, { "HISI02A1", APD_ADDR(hip07_i2c_desc) }, { "HISI02A2", APD_ADDR(hip08_i2c_desc) }, #endif diff --git a/drivers/acpi/acpi_configfs.c b/drivers/acpi/acpi_configfs.c index 853bc7fc673f..b58850389094 100644 --- a/drivers/acpi/acpi_configfs.c +++ b/drivers/acpi/acpi_configfs.c @@ -204,7 +204,7 @@ struct configfs_attribute *acpi_table_attrs[] = { NULL, }; -static struct config_item_type acpi_table_type = { +static const struct config_item_type acpi_table_type = { .ct_owner = THIS_MODULE, .ct_bin_attrs = acpi_table_bin_attrs, .ct_attrs = acpi_table_attrs, @@ -237,12 +237,12 @@ struct configfs_group_operations acpi_table_group_ops = { .drop_item = acpi_table_drop_item, }; -static struct config_item_type acpi_tables_type = { +static const struct config_item_type acpi_tables_type = { .ct_owner = THIS_MODULE, .ct_group_ops = &acpi_table_group_ops, }; -static struct config_item_type acpi_root_group_type = { +static const struct config_item_type acpi_root_group_type = { .ct_owner = THIS_MODULE, }; diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index 3ec05aa1a903..f21c99ec46ee 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c @@ -718,15 +718,15 @@ again: return size > 0 ? size : ret; } -static unsigned int acpi_aml_poll(struct file *file, poll_table *wait) +static __poll_t acpi_aml_poll(struct file *file, poll_table *wait) { - int masks = 0; + __poll_t masks = 0; poll_wait(file, &acpi_aml_io.wait, wait); if (acpi_aml_user_readable()) - masks |= POLLIN | POLLRDNORM; + masks |= EPOLLIN | EPOLLRDNORM; if (acpi_aml_user_writable()) - masks |= POLLOUT | POLLWRNORM; + masks |= EPOLLOUT | EPOLLWRNORM; return masks; } diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c new file mode 100644 index 000000000000..cf4fc0161164 --- /dev/null +++ b/drivers/acpi/acpi_lpit.c @@ -0,0 +1,163 @@ + +/* + * 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> +#include <linux/acpi.h> +#include <asm/msr.h> +#include <asm/tsc.h> + +struct lpit_residency_info { + struct acpi_generic_address gaddr; + u64 frequency; + void __iomem *iomem_addr; +}; + +/* Storage for an memory mapped and FFH based entries */ +static struct lpit_residency_info residency_info_mem; +static struct lpit_residency_info residency_info_ffh; + +static int lpit_read_residency_counter_us(u64 *counter, bool io_mem) +{ + int err; + + if (io_mem) { + u64 count = 0; + int error; + + error = acpi_os_read_iomem(residency_info_mem.iomem_addr, &count, + residency_info_mem.gaddr.bit_width); + if (error) + return error; + + *counter = div64_u64(count * 1000000ULL, residency_info_mem.frequency); + return 0; + } + + err = rdmsrl_safe(residency_info_ffh.gaddr.address, counter); + if (!err) { + u64 mask = GENMASK_ULL(residency_info_ffh.gaddr.bit_offset + + residency_info_ffh.gaddr. bit_width - 1, + residency_info_ffh.gaddr.bit_offset); + + *counter &= mask; + *counter >>= residency_info_ffh.gaddr.bit_offset; + *counter = div64_u64(*counter * 1000000ULL, residency_info_ffh.frequency); + return 0; + } + + return -ENODATA; +} + +static ssize_t low_power_idle_system_residency_us_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u64 counter; + int ret; + + ret = lpit_read_residency_counter_us(&counter, true); + if (ret) + return ret; + + return sprintf(buf, "%llu\n", counter); +} +static DEVICE_ATTR_RO(low_power_idle_system_residency_us); + +static ssize_t low_power_idle_cpu_residency_us_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u64 counter; + int ret; + + ret = lpit_read_residency_counter_us(&counter, false); + if (ret) + return ret; + + return sprintf(buf, "%llu\n", counter); +} +static DEVICE_ATTR_RO(low_power_idle_cpu_residency_us); + +int lpit_read_residency_count_address(u64 *address) +{ + if (!residency_info_mem.gaddr.address) + return -EINVAL; + + *address = residency_info_mem.gaddr.address; + + return 0; +} +EXPORT_SYMBOL_GPL(lpit_read_residency_count_address); + +static void lpit_update_residency(struct lpit_residency_info *info, + struct acpi_lpit_native *lpit_native) +{ + info->frequency = lpit_native->counter_frequency ? + lpit_native->counter_frequency : tsc_khz * 1000; + if (!info->frequency) + info->frequency = 1; + + info->gaddr = lpit_native->residency_counter; + if (info->gaddr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + info->iomem_addr = ioremap_nocache(info->gaddr.address, + info->gaddr.bit_width / 8); + if (!info->iomem_addr) + return; + + /* Silently fail, if cpuidle attribute group is not present */ + sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, + &dev_attr_low_power_idle_system_residency_us.attr, + "cpuidle"); + } else if (info->gaddr.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { + /* Silently fail, if cpuidle attribute group is not present */ + sysfs_add_file_to_group(&cpu_subsys.dev_root->kobj, + &dev_attr_low_power_idle_cpu_residency_us.attr, + "cpuidle"); + } +} + +static void lpit_process(u64 begin, u64 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) { + if (lpit_native->residency_counter.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && + !residency_info_mem.gaddr.address) { + lpit_update_residency(&residency_info_mem, lpit_native); + } else if (lpit_native->residency_counter.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && + !residency_info_ffh.gaddr.address) { + lpit_update_residency(&residency_info_ffh, lpit_native); + } + } + begin += lpit_native->header.length; + } +} + +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); + + if (ACPI_FAILURE(status)) + return; + + lpit_begin = (u64)lpit + sizeof(*lpit); + lpit_process(lpit_begin, lpit_begin + lpit->header.length); +} diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 032ae44710e5..2bcffec8dbf0 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -362,7 +362,7 @@ static int register_device_clock(struct acpi_device *adev, { const struct lpss_device_desc *dev_desc = pdata->dev_desc; const char *devname = dev_name(&adev->dev); - struct clk *clk = ERR_PTR(-ENODEV); + struct clk *clk; struct lpss_clk_data *clk_data; const char *parent, *clk_name; void __iomem *prv_base; @@ -427,6 +427,142 @@ out: return 0; } +struct lpss_device_links { + const char *supplier_hid; + const char *supplier_uid; + const char *consumer_hid; + const char *consumer_uid; + u32 flags; +}; + +/* + * The _DEP method is used to identify dependencies but instead of creating + * device links for every handle in _DEP, only links in the following list are + * created. That is necessary because, in the general case, _DEP can refer to + * devices that might not have drivers, or that are on different buses, or where + * the supplier is not enumerated until after the consumer is probed. + */ +static const struct lpss_device_links lpss_device_links[] = { + {"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME}, +}; + +static bool hid_uid_match(const char *hid1, const char *uid1, + const char *hid2, const char *uid2) +{ + return !strcmp(hid1, hid2) && uid1 && uid2 && !strcmp(uid1, uid2); +} + +static bool acpi_lpss_is_supplier(struct acpi_device *adev, + const struct lpss_device_links *link) +{ + return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev), + link->supplier_hid, link->supplier_uid); +} + +static bool acpi_lpss_is_consumer(struct acpi_device *adev, + const struct lpss_device_links *link) +{ + return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev), + link->consumer_hid, link->consumer_uid); +} + +struct hid_uid { + const char *hid; + const char *uid; +}; + +static int match_hid_uid(struct device *dev, void *data) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + struct hid_uid *id = data; + + if (!adev) + return 0; + + return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev), + id->hid, id->uid); +} + +static struct device *acpi_lpss_find_device(const char *hid, const char *uid) +{ + struct hid_uid data = { + .hid = hid, + .uid = uid, + }; + + return bus_find_device(&platform_bus_type, NULL, &data, match_hid_uid); +} + +static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) +{ + struct acpi_handle_list dep_devices; + acpi_status status; + int i; + + if (!acpi_has_method(adev->handle, "_DEP")) + return false; + + status = acpi_evaluate_reference(adev->handle, "_DEP", NULL, + &dep_devices); + if (ACPI_FAILURE(status)) { + dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n"); + return false; + } + + for (i = 0; i < dep_devices.count; i++) { + if (dep_devices.handles[i] == handle) + return true; + } + + return false; +} + +static void acpi_lpss_link_consumer(struct device *dev1, + const struct lpss_device_links *link) +{ + struct device *dev2; + + dev2 = acpi_lpss_find_device(link->consumer_hid, link->consumer_uid); + if (!dev2) + return; + + if (acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1))) + device_link_add(dev2, dev1, link->flags); + + put_device(dev2); +} + +static void acpi_lpss_link_supplier(struct device *dev1, + const struct lpss_device_links *link) +{ + struct device *dev2; + + dev2 = acpi_lpss_find_device(link->supplier_hid, link->supplier_uid); + if (!dev2) + return; + + if (acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2))) + device_link_add(dev1, dev2, link->flags); + + put_device(dev2); +} + +static void acpi_lpss_create_device_links(struct acpi_device *adev, + struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(lpss_device_links); i++) { + const struct lpss_device_links *link = &lpss_device_links[i]; + + if (acpi_lpss_is_supplier(adev, link)) + acpi_lpss_link_consumer(&pdev->dev, link); + + if (acpi_lpss_is_consumer(adev, link)) + acpi_lpss_link_supplier(&pdev->dev, link); + } +} + static int acpi_lpss_create_device(struct acpi_device *adev, const struct acpi_device_id *id) { @@ -465,6 +601,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev, acpi_dev_free_resource_list(&resource_list); if (!pdata->mmio_base) { + /* Avoid acpi_bus_attach() instantiating a pdev for this dev. */ + adev->pnp.type.platform_id = 0; /* Skip the device, but continue the namespace scan. */ ret = 0; goto err_out; @@ -500,6 +638,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, adev->driver_data = pdata; pdev = acpi_create_platform_device(adev, dev_desc->properties); if (!IS_ERR_OR_NULL(pdev)) { + acpi_lpss_create_device_links(adev, pdev); return 1; } @@ -693,7 +832,7 @@ static int acpi_lpss_activate(struct device *dev) struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; - ret = acpi_dev_runtime_resume(dev); + ret = acpi_dev_resume(dev); if (ret) return ret; @@ -713,43 +852,9 @@ static int acpi_lpss_activate(struct device *dev) static void acpi_lpss_dismiss(struct device *dev) { - acpi_dev_runtime_suspend(dev); + acpi_dev_suspend(dev, false); } -#ifdef CONFIG_PM_SLEEP -static int acpi_lpss_suspend_late(struct device *dev) -{ - struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); - int ret; - - ret = pm_generic_suspend_late(dev); - if (ret) - return ret; - - if (pdata->dev_desc->flags & LPSS_SAVE_CTX) - acpi_lpss_save_ctx(dev, pdata); - - return acpi_dev_suspend_late(dev); -} - -static int acpi_lpss_resume_early(struct device *dev) -{ - struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); - int ret; - - ret = acpi_dev_resume_early(dev); - if (ret) - return ret; - - acpi_lpss_d3_to_d0_delay(pdata); - - if (pdata->dev_desc->flags & LPSS_SAVE_CTX) - acpi_lpss_restore_ctx(dev, pdata); - - return pm_generic_resume_early(dev); -} -#endif /* CONFIG_PM_SLEEP */ - /* IOSF SB for LPSS island */ #define LPSS_IOSF_UNIT_LPIOEP 0xA0 #define LPSS_IOSF_UNIT_LPIO1 0xAB @@ -835,19 +940,15 @@ static void lpss_iosf_exit_d3_state(void) mutex_unlock(&lpss_iosf_mutex); } -static int acpi_lpss_runtime_suspend(struct device *dev) +static int acpi_lpss_suspend(struct device *dev, bool wakeup) { struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; - ret = pm_generic_runtime_suspend(dev); - if (ret) - return ret; - if (pdata->dev_desc->flags & LPSS_SAVE_CTX) acpi_lpss_save_ctx(dev, pdata); - ret = acpi_dev_runtime_suspend(dev); + ret = acpi_dev_suspend(dev, wakeup); /* * This call must be last in the sequence, otherwise PMC will return @@ -860,7 +961,7 @@ static int acpi_lpss_runtime_suspend(struct device *dev) return ret; } -static int acpi_lpss_runtime_resume(struct device *dev) +static int acpi_lpss_resume(struct device *dev) { struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; @@ -872,7 +973,7 @@ static int acpi_lpss_runtime_resume(struct device *dev) if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available()) lpss_iosf_exit_d3_state(); - ret = acpi_dev_runtime_resume(dev); + ret = acpi_dev_resume(dev); if (ret) return ret; @@ -881,7 +982,41 @@ static int acpi_lpss_runtime_resume(struct device *dev) if (pdata->dev_desc->flags & LPSS_SAVE_CTX) acpi_lpss_restore_ctx(dev, pdata); - return pm_generic_runtime_resume(dev); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int acpi_lpss_suspend_late(struct device *dev) +{ + int ret; + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + ret = pm_generic_suspend_late(dev); + return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev)); +} + +static int acpi_lpss_resume_early(struct device *dev) +{ + int ret = acpi_lpss_resume(dev); + + return ret ? ret : pm_generic_resume_early(dev); +} +#endif /* CONFIG_PM_SLEEP */ + +static int acpi_lpss_runtime_suspend(struct device *dev) +{ + int ret = pm_generic_runtime_suspend(dev); + + return ret ? ret : acpi_lpss_suspend(dev, true); +} + +static int acpi_lpss_runtime_resume(struct device *dev) +{ + int ret = acpi_lpss_resume(dev); + + return ret ? ret : pm_generic_runtime_resume(dev); } #endif /* CONFIG_PM */ @@ -894,13 +1029,20 @@ static struct dev_pm_domain acpi_lpss_pm_domain = { #ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP .prepare = acpi_subsys_prepare, - .complete = pm_complete_with_resume_check, + .complete = acpi_subsys_complete, .suspend = acpi_subsys_suspend, .suspend_late = acpi_lpss_suspend_late, + .suspend_noirq = acpi_subsys_suspend_noirq, + .resume_noirq = acpi_subsys_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, #endif .runtime_suspend = acpi_lpss_runtime_suspend, diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 86c10599d9f8..449d86d39965 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -82,6 +82,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev) * PIIX4 models. */ errata.piix4.throttle = 1; + /* fall through*/ case 2: /* PIIX4E */ case 3: /* PIIX4M */ diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 0972ec0e2eb8..76fb96966f7b 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -53,7 +53,7 @@ MODULE_AUTHOR("Bruno Ducrot"); MODULE_DESCRIPTION("ACPI Video Driver"); MODULE_LICENSE("GPL"); -static bool brightness_switch_enabled = 1; +static bool brightness_switch_enabled = true; module_param(brightness_switch_enabled, bool, 0644); /* @@ -80,8 +80,8 @@ MODULE_PARM_DESC(report_key_events, static bool device_id_scheme = false; module_param(device_id_scheme, bool, 0444); -static bool only_lcd = false; -module_param(only_lcd, bool, 0444); +static int only_lcd = -1; +module_param(only_lcd, int, 0444); static int register_count; static DEFINE_MUTEX(register_count_mutex); @@ -2136,6 +2136,16 @@ int acpi_video_register(void) goto leave; } + /* + * We're seeing a lot of bogus backlight interfaces on newer machines + * without a LCD such as desktops, servers and HDMI sticks. Checking + * the lcd flag fixes this, so enable this on any machines which are + * win8 ready (where we also prefer the native backlight driver, so + * normally the acpi_video code should not register there anyways). + */ + if (only_lcd == -1) + only_lcd = acpi_osi_is_win8(); + dmi_check_system(video_dmi_table); ret = acpi_bus_register_driver(&acpi_video_bus); diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index e05232da0588..71f6f2624deb 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -178,6 +178,7 @@ acpi-y += \ utresrc.o \ utstate.o \ utstring.o \ + utstrsuppt.o \ utstrtoul64.o \ utxface.o \ utxfinit.o \ diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index 7a1a68b5ac5c..e65478593f9a 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,7 +51,7 @@ /* Common info for tool signons */ #define ACPICA_NAME "Intel ACPI Component Architecture" -#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2017 Intel Corporation" +#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2018 Intel Corporation" #if ACPI_MACHINE_WIDTH == 64 #define ACPI_WIDTH " (64-bit version)" @@ -80,6 +80,9 @@ prefix, ACPICA_COPYRIGHT, \ prefix +#define ACPI_COMMON_BUILD_TIME \ + "Build date/time: %s %s\n", __DATE__, __TIME__ + /* Macros for usage messages */ #define ACPI_USAGE_HEADER(usage) \ diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 49bf47ca5477..c349ffdf5557 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acconvert.h b/drivers/acpi/acpica/acconvert.h index c84223b60b35..ce6e8db83e27 100644 --- a/drivers/acpi/acpica/acconvert.h +++ b/drivers/acpi/acpica/acconvert.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 71743e5252f5..8b2cca5a717b 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -223,6 +223,10 @@ void acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags); void +acpi_db_create_execution_thread(char *method_name_arg, + char **arguments, acpi_object_type *types); + +void acpi_db_create_execution_threads(char *num_threads_arg, char *num_loops_arg, char *method_name_arg); diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index f8f3a6e74128..fab590bc5fd3 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index a2adfd42f85c..1b0269f6ac2d 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 95eed442703f..27f322b2fed1 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ /***************************************************************************** * - * Globals related to the ACPI tables + * Globals related to the incoming ACPI tables * ****************************************************************************/ @@ -87,7 +87,7 @@ ACPI_GLOBAL(u8, acpi_gbl_integer_nybble_width); /***************************************************************************** * - * Mutual exclusion within ACPICA subsystem + * Mutual exclusion within the ACPICA subsystem * ****************************************************************************/ @@ -167,7 +167,7 @@ ACPI_GLOBAL(u8, acpi_gbl_next_owner_id_offset); ACPI_INIT_GLOBAL(u8, acpi_gbl_namespace_initialized, FALSE); -/* Misc */ +/* Miscellaneous */ ACPI_GLOBAL(u32, acpi_gbl_original_mode); ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); @@ -191,10 +191,9 @@ extern const char acpi_gbl_lower_hex_digits[]; extern const char acpi_gbl_upper_hex_digits[]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - /* Lists for tracking memory allocations (debug only) */ +#ifdef ACPI_DBG_TRACK_ALLOCATIONS ACPI_GLOBAL(struct acpi_memory_list *, acpi_gbl_global_list); ACPI_GLOBAL(struct acpi_memory_list *, acpi_gbl_ns_node_list); ACPI_GLOBAL(u8, acpi_gbl_display_final_mem_stats); @@ -203,7 +202,7 @@ ACPI_GLOBAL(u8, acpi_gbl_disable_mem_tracking); /***************************************************************************** * - * Namespace globals + * ACPI Namespace * ****************************************************************************/ @@ -234,15 +233,20 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_nesting_level, 0); /***************************************************************************** * - * Interpreter globals + * Interpreter/Parser globals * ****************************************************************************/ -ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list); - /* Control method single step flag */ ACPI_GLOBAL(u8, acpi_gbl_cm_single_step); +ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list); +ACPI_INIT_GLOBAL(union acpi_parse_object, *acpi_gbl_current_scope, NULL); + +/* ASL/ASL+ converter */ + +ACPI_INIT_GLOBAL(u8, acpi_gbl_capture_comments, FALSE); +ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_last_list_head, NULL); /***************************************************************************** * @@ -252,7 +256,6 @@ ACPI_GLOBAL(u8, acpi_gbl_cm_single_step); extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; - ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); @@ -263,7 +266,6 @@ ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); ****************************************************************************/ #if (!ACPI_REDUCED_HARDWARE) - ACPI_GLOBAL(u8, acpi_gbl_all_gpes_initialized); ACPI_GLOBAL(struct acpi_gpe_xrupt_info *, acpi_gbl_gpe_xrupt_list_head); ACPI_GLOBAL(struct acpi_gpe_block_info *, @@ -272,10 +274,8 @@ ACPI_GLOBAL(acpi_gbl_event_handler, acpi_gbl_global_event_handler); ACPI_GLOBAL(void *, acpi_gbl_global_event_handler_context); ACPI_GLOBAL(struct acpi_fixed_event_handler, acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]); - extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; - #endif /* !ACPI_REDUCED_HARDWARE */ /***************************************************************************** @@ -291,14 +291,14 @@ ACPI_GLOBAL(u32, acpi_gpe_count); ACPI_GLOBAL(u32, acpi_sci_count); ACPI_GLOBAL(u32, acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]); -/* Support for dynamic control method tracing mechanism */ +/* Dynamic control method tracing mechanism */ ACPI_GLOBAL(u32, acpi_gbl_original_dbg_level); ACPI_GLOBAL(u32, acpi_gbl_original_dbg_layer); /***************************************************************************** * - * Debugger and Disassembler globals + * Debugger and Disassembler * ****************************************************************************/ @@ -326,7 +326,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list); #endif #ifdef ACPI_DEBUGGER - ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE); ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID); @@ -340,7 +339,6 @@ ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level); ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node); ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop); ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated); - ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]); ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]); @@ -350,32 +348,33 @@ ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]); ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]); ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]); -/* - * Statistic globals - */ +/* Statistics globals */ + ACPI_GLOBAL(u16, acpi_gbl_obj_type_count[ACPI_TOTAL_TYPES]); ACPI_GLOBAL(u16, acpi_gbl_node_type_count[ACPI_TOTAL_TYPES]); ACPI_GLOBAL(u16, acpi_gbl_obj_type_count_misc); ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); ACPI_GLOBAL(u32, acpi_gbl_num_nodes); ACPI_GLOBAL(u32, acpi_gbl_num_objects); - #endif /* ACPI_DEBUGGER */ #if defined (ACPI_DISASSEMBLER) || defined (ACPI_ASL_COMPILER) - ACPI_GLOBAL(const char, *acpi_gbl_pld_panel_list[]); ACPI_GLOBAL(const char, *acpi_gbl_pld_vertical_position_list[]); ACPI_GLOBAL(const char, *acpi_gbl_pld_horizontal_position_list[]); ACPI_GLOBAL(const char, *acpi_gbl_pld_shape_list[]); - ACPI_INIT_GLOBAL(u8, acpi_gbl_disasm_flag, FALSE); - #endif -/* - * Meant for the -ca option. - */ +/***************************************************************************** + * + * ACPICA application-specific globals + * + ****************************************************************************/ + +/* ASL-to-ASL+ conversion utility (implemented within the iASL compiler) */ + +#ifdef ACPI_ASL_COMPILER ACPI_INIT_GLOBAL(char *, acpi_gbl_current_inline_comment, NULL); ACPI_INIT_GLOBAL(char *, acpi_gbl_current_end_node_comment, NULL); ACPI_INIT_GLOBAL(char *, acpi_gbl_current_open_brace_comment, NULL); @@ -386,23 +385,18 @@ ACPI_INIT_GLOBAL(char *, acpi_gbl_current_filename, NULL); ACPI_INIT_GLOBAL(char *, acpi_gbl_current_parent_filename, NULL); ACPI_INIT_GLOBAL(char *, acpi_gbl_current_include_filename, NULL); -ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_last_list_head, NULL); - ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_def_blk_comment_list_head, NULL); ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_def_blk_comment_list_tail, NULL); - ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_reg_comment_list_head, NULL); ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_reg_comment_list_tail, NULL); - ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_inc_comment_list_head, NULL); ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_inc_comment_list_tail, NULL); - ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_end_blk_comment_list_head, NULL); ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_end_blk_comment_list_tail, @@ -410,30 +404,18 @@ ACPI_INIT_GLOBAL(struct acpi_comment_node, *acpi_gbl_end_blk_comment_list_tail, ACPI_INIT_GLOBAL(struct acpi_comment_addr_node, *acpi_gbl_comment_addr_list_head, NULL); - -ACPI_INIT_GLOBAL(union acpi_parse_object, *acpi_gbl_current_scope, NULL); - ACPI_INIT_GLOBAL(struct acpi_file_node, *acpi_gbl_file_tree_root, NULL); ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_reg_comment_cache); ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_comment_addr_cache); ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_file_cache); -ACPI_INIT_GLOBAL(u8, gbl_capture_comments, FALSE); - ACPI_INIT_GLOBAL(u8, acpi_gbl_debug_asl_conversion, FALSE); ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_conv_debug_file, NULL); - ACPI_GLOBAL(char, acpi_gbl_table_sig[4]); - -/***************************************************************************** - * - * Application globals - * - ****************************************************************************/ +#endif #ifdef ACPI_APPLICATION - ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); ACPI_INIT_GLOBAL(u8, acpi_gbl_debug_timeout, FALSE); @@ -442,16 +424,6 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_debug_timeout, FALSE); ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock); /* For print buffer */ ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]); - #endif /* ACPI_APPLICATION */ -/***************************************************************************** - * - * Info/help support - * - ****************************************************************************/ - -extern const struct ah_predefined_name asl_predefined_info[]; -extern const struct ah_device_id asl_device_ids[]; - #endif /* __ACGLOBAL_H__ */ diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index fd4f3cacb356..3569aa3bf5ee 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,9 +66,9 @@ acpi_status acpi_hw_validate_register(struct acpi_generic_address *reg, u8 max_bit_width, u64 *address); -acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); +acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg); -acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); +acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg); struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 29a863c85318..744374ab9285 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -101,7 +101,8 @@ typedef const struct acpi_exdump_info { */ acpi_status acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, u32 flags); + union acpi_operand_object **result_desc, + u32 implicit_conversion); acpi_status acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, @@ -424,9 +425,6 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, struct acpi_walk_state *walk_state, u8 implicit_conversion); -#define ACPI_IMPLICIT_CONVERSION TRUE -#define ACPI_NO_IMPLICIT_CONVERSION FALSE - /* * exstoren - resolve/store object */ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 0d45b8bb1678..3ba3ff0f1c04 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -622,7 +622,7 @@ struct acpi_control_state { union acpi_parse_object *predicate_op; u8 *aml_predicate_start; /* Start of if/while predicate */ u8 *package_end; /* End of if/while block */ - u32 loop_count; /* While() loop counter */ + u64 loop_timeout; /* While() loop timeout */ }; /* @@ -1218,16 +1218,17 @@ struct acpi_db_method_info { acpi_object_type *types; /* - * Arguments to be passed to method for the command - * Threads - - * the Number of threads, ID of current thread and - * Index of current thread inside all them created. + * Arguments to be passed to method for the commands Threads and + * Background. Note, ACPI specifies a maximum of 7 arguments (0 - 6). + * + * For the Threads command, the Number of threads, ID of current + * thread and Index of current thread inside all them created. */ char init_args; #ifdef ACPI_DEBUGGER - acpi_object_type arg_types[4]; + acpi_object_type arg_types[ACPI_METHOD_NUM_ARGS]; #endif - char *arguments[4]; + char *arguments[ACPI_METHOD_NUM_ARGS]; char num_threads_str[11]; char id_of_thread_str[11]; char index_of_thread_str[11]; diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index c7f0c96cc00f..6463340c4522 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -455,7 +455,7 @@ * the plist contains a set of parens to allow variable-length lists. * These macros are used for both the debug and non-debug versions of the code. */ -#define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e); +#define ACPI_ERROR_NAMESPACE(s, p, e) acpi_ut_prefixed_namespace_error (AE_INFO, s, p, e); #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e); #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 54a0c51b3e37..6c8f364fe2fc 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -289,6 +289,9 @@ acpi_ns_build_normalized_path(struct acpi_namespace_node *node, char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, u8 no_trailing); +char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope, + const char *internal_path); + char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state); acpi_status diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 5226146190bf..a1f4d3f385c8 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index cbd59a302679..36c2c5825986 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index c23c47328060..e25634951d03 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index cdfcad8eb74c..7c27bcee6ac7 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 438f3098a093..20f36949928a 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 62134bdbeda6..0338ac32f9c6 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 84a3ceb6e384..15b23414245a 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 745134ade35f..00d21d2f766e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -118,9 +118,6 @@ extern const char *acpi_gbl_ptyp_decode[]; #ifndef ACPI_MSG_ERROR #define ACPI_MSG_ERROR "ACPI Error: " #endif -#ifndef ACPI_MSG_EXCEPTION -#define ACPI_MSG_EXCEPTION "ACPI Exception: " -#endif #ifndef ACPI_MSG_WARNING #define ACPI_MSG_WARNING "ACPI Warning: " #endif @@ -129,10 +126,10 @@ extern const char *acpi_gbl_ptyp_decode[]; #endif #ifndef ACPI_MSG_BIOS_ERROR -#define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): " +#define ACPI_MSG_BIOS_ERROR "Firmware Error (ACPI): " #endif #ifndef ACPI_MSG_BIOS_WARNING -#define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): " +#define ACPI_MSG_BIOS_WARNING "Firmware Warning (ACPI): " #endif /* @@ -141,6 +138,11 @@ extern const char *acpi_gbl_ptyp_decode[]; #define ACPI_MSG_SUFFIX \ acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) +/* Flags to indicate implicit or explicit string-to-integer conversion */ + +#define ACPI_IMPLICIT_CONVERSION TRUE +#define ACPI_NO_IMPLICIT_CONVERSION FALSE + /* Types for Resource descriptor entries */ #define ACPI_INVALID_RESOURCE 0 @@ -197,25 +199,41 @@ void acpi_ut_strlwr(char *src_string); int acpi_ut_stricmp(char *string1, char *string2); -acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *ret_integer); +/* + * utstrsuppt - string-to-integer conversion support functions + */ +acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value); + +acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr); + +acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr); + +char acpi_ut_remove_whitespace(char **string); + +char acpi_ut_remove_leading_zeros(char **string); + +u8 acpi_ut_detect_hex_prefix(char **string); + +u8 acpi_ut_detect_octal_prefix(char **string); /* - * Values for Flags above - * Note: LIMIT values correspond to acpi_gbl_integer_byte_width values (4/8) + * utstrtoul64 - string-to-integer conversion functions */ -#define ACPI_STRTOUL_32BIT 0x04 /* 4 bytes */ -#define ACPI_STRTOUL_64BIT 0x08 /* 8 bytes */ -#define ACPI_STRTOUL_BASE16 0x10 /* Default: Base10/16 */ +acpi_status acpi_ut_strtoul64(char *string, u64 *ret_integer); + +u64 acpi_ut_explicit_strtoul64(char *string); + +u64 acpi_ut_implicit_strtoul64(char *string); /* * utglobal - Global data structures and procedures */ acpi_status acpi_ut_init_globals(void); -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) - const char *acpi_ut_get_mutex_name(u32 mutex_id); +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type); #endif @@ -620,9 +638,11 @@ void ut_convert_backslashes(char *pathname); void acpi_ut_repair_name(char *name); -#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) +#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) || defined (ACPI_DEBUG_OUTPUT) u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source); +void acpi_ut_safe_strncpy(char *dest, char *source, acpi_size dest_size); + u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source); u8 @@ -716,9 +736,11 @@ acpi_ut_predefined_bios_error(const char *module_name, u8 node_flags, const char *format, ...); void -acpi_ut_namespace_error(const char *module_name, - u32 line_number, - const char *internal_name, acpi_status lookup_status); +acpi_ut_prefixed_namespace_error(const char *module_name, + u32 line_number, + union acpi_generic_state *prefix_scope, + const char *internal_name, + acpi_status lookup_status); void acpi_ut_method_error(const char *module_name, diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index f54dc5a34bdc..b0e9492a6297 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 1236e9a414e4..b680c229ddd5 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbcmds.c b/drivers/acpi/acpica/dbcmds.c index 5984b90eb590..4112c85f2aab 100644 --- a/drivers/acpi/acpica/dbcmds.c +++ b/drivers/acpi/acpica/dbcmds.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c index 857dbc43a9b1..27236a6c51ff 100644 --- a/drivers/acpi/acpica/dbconvert.c +++ b/drivers/acpi/acpica/dbconvert.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -277,10 +277,7 @@ acpi_db_convert_to_object(acpi_object_type type, default: object->type = ACPI_TYPE_INTEGER; - status = acpi_ut_strtoul64(string, - (acpi_gbl_integer_byte_width | - ACPI_STRTOUL_BASE16), - &object->integer.value); + status = acpi_ut_strtoul64(string, &object->integer.value); break; } diff --git a/drivers/acpi/acpica/dbdisply.c b/drivers/acpi/acpica/dbdisply.c index 5a606eac0c22..7df920cda77d 100644 --- a/drivers/acpi/acpica/dbdisply.c +++ b/drivers/acpi/acpica/dbdisply.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbexec.c b/drivers/acpi/acpica/dbexec.c index 3b30319752f0..8ad9e6d9e54b 100644 --- a/drivers/acpi/acpica/dbexec.c +++ b/drivers/acpi/acpica/dbexec.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,6 +67,8 @@ static acpi_status acpi_db_execution_walk(acpi_handle obj_handle, u32 nesting_level, void *context, void **return_value); +static void ACPI_SYSTEM_XFACE acpi_db_single_execution_thread(void *context); + /******************************************************************************* * * FUNCTION: acpi_db_delete_objects @@ -229,7 +231,7 @@ static acpi_status acpi_db_execute_setup(struct acpi_db_method_info *info) ACPI_FUNCTION_NAME(db_execute_setup); - /* Catenate the current scope to the supplied name */ + /* Concatenate the current scope to the supplied name */ info->pathname[0] = 0; if ((info->name[0] != '\\') && (info->name[0] != '/')) { @@ -611,6 +613,112 @@ static void ACPI_SYSTEM_XFACE acpi_db_method_thread(void *context) /******************************************************************************* * + * FUNCTION: acpi_db_single_execution_thread + * + * PARAMETERS: context - Method info struct + * + * RETURN: None + * + * DESCRIPTION: Create one thread and execute a method + * + ******************************************************************************/ + +static void ACPI_SYSTEM_XFACE acpi_db_single_execution_thread(void *context) +{ + struct acpi_db_method_info *info = context; + acpi_status status; + struct acpi_buffer return_obj; + + acpi_os_printf("\n"); + + status = acpi_db_execute_method(info, &return_obj); + if (ACPI_FAILURE(status)) { + acpi_os_printf("%s During evaluation of %s\n", + acpi_format_exception(status), info->pathname); + return; + } + + /* Display a return object, if any */ + + if (return_obj.length) { + acpi_os_printf("Evaluation of %s returned object %p, " + "external buffer length %X\n", + acpi_gbl_db_method_info.pathname, + return_obj.pointer, (u32)return_obj.length); + + acpi_db_dump_external_object(return_obj.pointer, 1); + } + + acpi_os_printf("\nBackground thread completed\n%c ", + ACPI_DEBUGGER_COMMAND_PROMPT); +} + +/******************************************************************************* + * + * FUNCTION: acpi_db_create_execution_thread + * + * PARAMETERS: method_name_arg - Control method to execute + * arguments - Array of arguments to the method + * types - Corresponding array of object types + * + * RETURN: None + * + * DESCRIPTION: Create a single thread to evaluate a namespace object. Handles + * arguments passed on command line for control methods. + * + ******************************************************************************/ + +void +acpi_db_create_execution_thread(char *method_name_arg, + char **arguments, acpi_object_type *types) +{ + acpi_status status; + u32 i; + + memset(&acpi_gbl_db_method_info, 0, sizeof(struct acpi_db_method_info)); + acpi_gbl_db_method_info.name = method_name_arg; + acpi_gbl_db_method_info.init_args = 1; + acpi_gbl_db_method_info.args = acpi_gbl_db_method_info.arguments; + acpi_gbl_db_method_info.types = acpi_gbl_db_method_info.arg_types; + + /* Setup method arguments, up to 7 (0-6) */ + + for (i = 0; (i < ACPI_METHOD_NUM_ARGS) && *arguments; i++) { + acpi_gbl_db_method_info.arguments[i] = *arguments; + arguments++; + + acpi_gbl_db_method_info.arg_types[i] = *types; + types++; + } + + status = acpi_db_execute_setup(&acpi_gbl_db_method_info); + if (ACPI_FAILURE(status)) { + return; + } + + /* Get the NS node, determines existence also */ + + status = acpi_get_handle(NULL, acpi_gbl_db_method_info.pathname, + &acpi_gbl_db_method_info.method); + if (ACPI_FAILURE(status)) { + acpi_os_printf("%s Could not get handle for %s\n", + acpi_format_exception(status), + acpi_gbl_db_method_info.pathname); + return; + } + + status = acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD, + acpi_db_single_execution_thread, + &acpi_gbl_db_method_info); + if (ACPI_FAILURE(status)) { + return; + } + + acpi_os_printf("\nBackground thread started\n"); +} + +/******************************************************************************* + * * FUNCTION: acpi_db_create_execution_threads * * PARAMETERS: num_threads_arg - Number of threads to create diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c index 4d81ea291d93..084bb332f8e2 100644 --- a/drivers/acpi/acpica/dbfileio.c +++ b/drivers/acpi/acpica/dbfileio.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,8 +99,8 @@ void acpi_db_open_debug_file(char *name) } acpi_os_printf("Debug output file %s opened\n", name); - strncpy(acpi_gbl_db_debug_filename, name, - sizeof(acpi_gbl_db_debug_filename)); + acpi_ut_safe_strncpy(acpi_gbl_db_debug_filename, name, + sizeof(acpi_gbl_db_debug_filename)); acpi_gbl_db_output_to_file = TRUE; } #endif diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c index 7d08974c64c2..55c0f2742339 100644 --- a/drivers/acpi/acpica/dbhistry.c +++ b/drivers/acpi/acpica/dbhistry.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 2626d79db064..f7c661e06f37 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -136,6 +136,7 @@ enum acpi_ex_debugger_commands { CMD_UNLOAD, CMD_TERMINATE, + CMD_BACKGROUND, CMD_THREADS, CMD_TEST, @@ -212,6 +213,7 @@ static const struct acpi_db_command_info acpi_gbl_db_commands[] = { {"UNLOAD", 1}, {"TERMINATE", 0}, + {"BACKGROUND", 1}, {"THREADS", 3}, {"TEST", 1}, @@ -222,9 +224,56 @@ static const struct acpi_db_command_info acpi_gbl_db_commands[] = { /* * Help for all debugger commands. First argument is the number of lines * of help to output for the command. + * + * Note: Some commands are not supported by the kernel-level version of + * the debugger. */ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { - {0, "\nGeneral-Purpose Commands:", "\n"}, + {0, "\nNamespace Access:", "\n"}, + {1, " Businfo", "Display system bus info\n"}, + {1, " Disassemble <Method>", "Disassemble a control method\n"}, + {1, " Find <AcpiName> (? is wildcard)", + "Find ACPI name(s) with wildcards\n"}, + {1, " Integrity", "Validate namespace integrity\n"}, + {1, " Methods", "Display list of loaded control methods\n"}, + {1, " Namespace [Object] [Depth]", + "Display loaded namespace tree/subtree\n"}, + {1, " Notify <Object> <Value>", "Send a notification on Object\n"}, + {1, " Objects [ObjectType]", + "Display summary of all objects or just given type\n"}, + {1, " Owner <OwnerId> [Depth]", + "Display loaded namespace by object owner\n"}, + {1, " Paths", "Display full pathnames of namespace objects\n"}, + {1, " Predefined", "Check all predefined names\n"}, + {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"}, + {1, " References <Addr>", "Find all references to object at addr\n"}, + {1, " Resources [DeviceName]", + "Display Device resources (no arg = all devices)\n"}, + {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"}, + {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"}, + {1, " Type <Object>", "Display object type\n"}, + + {0, "\nControl Method Execution:", "\n"}, + {1, " Evaluate <Namepath> [Arguments]", + "Evaluate object or control method\n"}, + {1, " Execute <Namepath> [Arguments]", "Synonym for Evaluate\n"}, +#ifdef ACPI_APPLICATION + {1, " Background <Namepath> [Arguments]", + "Evaluate object/method in a separate thread\n"}, + {1, " Thread <Threads><Loops><NamePath>", + "Spawn threads to execute method(s)\n"}, +#endif + {1, " Debug <Namepath> [Arguments]", "Single-Step a control method\n"}, + {7, " [Arguments] formats:", "Control method argument formats\n"}, + {1, " Hex Integer", "Integer\n"}, + {1, " \"Ascii String\"", "String\n"}, + {1, " (Hex Byte List)", "Buffer\n"}, + {1, " (01 42 7A BF)", "Buffer example (4 bytes)\n"}, + {1, " [Package Element List]", "Package\n"}, + {1, " [0x01 0x1234 \"string\"]", + "Package example (3 elements)\n"}, + + {0, "\nMiscellaneous:", "\n"}, {1, " Allocations", "Display list of current memory allocations\n"}, {2, " Dump <Address>|<Namepath>", "\n"}, {0, " [Byte|Word|Dword|Qword]", @@ -248,46 +297,30 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { {1, " Stack", "Display CPU stack usage\n"}, {1, " Tables", "Info about current ACPI table(s)\n"}, {1, " Tables", "Display info about loaded ACPI tables\n"}, +#ifdef ACPI_APPLICATION + {1, " Terminate", "Delete namespace and all internal objects\n"}, +#endif {1, " ! <CommandNumber>", "Execute command from history buffer\n"}, {1, " !!", "Execute last command again\n"}, - {0, "\nNamespace Access Commands:", "\n"}, - {1, " Businfo", "Display system bus info\n"}, - {1, " Disassemble <Method>", "Disassemble a control method\n"}, - {1, " Find <AcpiName> (? is wildcard)", - "Find ACPI name(s) with wildcards\n"}, - {1, " Integrity", "Validate namespace integrity\n"}, - {1, " Methods", "Display list of loaded control methods\n"}, - {1, " Namespace [Object] [Depth]", - "Display loaded namespace tree/subtree\n"}, - {1, " Notify <Object> <Value>", "Send a notification on Object\n"}, - {1, " Objects [ObjectType]", - "Display summary of all objects or just given type\n"}, - {1, " Owner <OwnerId> [Depth]", - "Display loaded namespace by object owner\n"}, - {1, " Paths", "Display full pathnames of namespace objects\n"}, - {1, " Predefined", "Check all predefined names\n"}, - {1, " Prefix [<Namepath>]", "Set or Get current execution prefix\n"}, - {1, " References <Addr>", "Find all references to object at addr\n"}, - {1, " Resources [DeviceName]", - "Display Device resources (no arg = all devices)\n"}, - {1, " Set N <NamedObject> <Value>", "Set value for named integer\n"}, - {1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"}, - {1, " Type <Object>", "Display object type\n"}, + {0, "\nMethod and Namespace Debugging:", "\n"}, + {5, " Trace <State> [<Namepath>] [Once]", + "Trace control method execution\n"}, + {1, " Enable", "Enable all messages\n"}, + {1, " Disable", "Disable tracing\n"}, + {1, " Method", "Enable method execution messages\n"}, + {1, " Opcode", "Enable opcode execution messages\n"}, + {3, " Test <TestName>", "Invoke a debug test\n"}, + {1, " Objects", "Read/write/compare all namespace data objects\n"}, + {1, " Predefined", + "Validate all ACPI predefined names (_STA, etc.)\n"}, + {1, " Execute predefined", + "Execute all predefined (public) methods\n"}, - {0, "\nControl Method Execution Commands:", "\n"}, + {0, "\nControl Method Single-Step Execution:", "\n"}, {1, " Arguments (or Args)", "Display method arguments\n"}, {1, " Breakpoint <AmlOffset>", "Set an AML execution breakpoint\n"}, {1, " Call", "Run to next control method invocation\n"}, - {1, " Debug <Namepath> [Arguments]", "Single Step a control method\n"}, - {6, " Evaluate", "Synonym for Execute\n"}, - {5, " Execute <Namepath> [Arguments]", "Execute control method\n"}, - {1, " Hex Integer", "Integer method argument\n"}, - {1, " \"Ascii String\"", "String method argument\n"}, - {1, " (Hex Byte List)", "Buffer method argument\n"}, - {1, " [Package Element List]", "Package method argument\n"}, - {5, " Execute predefined", - "Execute all predefined (public) methods\n"}, {1, " Go", "Allow method to run to completion\n"}, {1, " Information", "Display info about the current method\n"}, {1, " Into", "Step into (not over) a method call\n"}, @@ -296,41 +329,24 @@ static const struct acpi_db_command_help acpi_gbl_db_command_help[] = { {1, " Results", "Display method result stack\n"}, {1, " Set <A|L> <#> <Value>", "Set method data (Arguments/Locals)\n"}, {1, " Stop", "Terminate control method\n"}, - {5, " Trace <State> [<Namepath>] [Once]", - "Trace control method execution\n"}, - {1, " Enable", "Enable all messages\n"}, - {1, " Disable", "Disable tracing\n"}, - {1, " Method", "Enable method execution messages\n"}, - {1, " Opcode", "Enable opcode execution messages\n"}, {1, " Tree", "Display control method calling tree\n"}, {1, " <Enter>", "Single step next AML opcode (over calls)\n"}, #ifdef ACPI_APPLICATION - {0, "\nHardware Simulation Commands:", "\n"}, - {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"}, - {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"}, - {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"}, - {1, " Gpes", "Display info on all GPE devices\n"}, - {1, " Sci", "Generate an SCI\n"}, - {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"}, - - {0, "\nFile I/O Commands:", "\n"}, + {0, "\nFile Operations:", "\n"}, {1, " Close", "Close debug output file\n"}, {1, " Load <Input Filename>", "Load ACPI table from a file\n"}, {1, " Open <Output Filename>", "Open a file for debug output\n"}, {1, " Unload <Namepath>", "Unload an ACPI table via namespace object\n"}, - {0, "\nUser Space Commands:", "\n"}, - {1, " Terminate", "Delete namespace and all internal objects\n"}, - {1, " Thread <Threads><Loops><NamePath>", - "Spawn threads to execute method(s)\n"}, - - {0, "\nDebug Test Commands:", "\n"}, - {3, " Test <TestName>", "Invoke a debug test\n"}, - {1, " Objects", "Read/write/compare all namespace data objects\n"}, - {1, " Predefined", - "Execute all ACPI predefined names (_STA, etc.)\n"}, + {0, "\nHardware Simulation:", "\n"}, + {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"}, + {1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"}, + {1, " Gpe <GpeNum> [GpeBlockDevice]", "Simulate a GPE\n"}, + {1, " Gpes", "Display info on all GPE devices\n"}, + {1, " Sci", "Generate an SCI\n"}, + {1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"}, #endif {0, NULL, NULL} }; @@ -442,11 +458,15 @@ static void acpi_db_display_help(char *command) /* No argument to help, display help for all commands */ + acpi_os_printf("\nSummary of AML Debugger Commands\n\n"); + while (next->invocation) { acpi_os_printf("%-38s%s", next->invocation, next->description); next++; } + acpi_os_printf("\n"); + } else { /* Display help for all commands that match the subtring */ @@ -1087,6 +1107,13 @@ acpi_db_command_dispatch(char *input_buffer, /* acpi_initialize (NULL); */ break; + case CMD_BACKGROUND: + + acpi_db_create_execution_thread(acpi_gbl_db_args[1], + &acpi_gbl_db_args[2], + &acpi_gbl_db_arg_types[2]); + break; + case CMD_THREADS: acpi_db_create_execution_threads(acpi_gbl_db_args[1], diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c index df62c9245efc..2cda0bff6f2c 100644 --- a/drivers/acpi/acpica/dbmethod.c +++ b/drivers/acpi/acpica/dbmethod.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c index 8c207c772517..8796fc1e0360 100644 --- a/drivers/acpi/acpica/dbnames.c +++ b/drivers/acpi/acpica/dbnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c index e7b415c20aa8..d2063cbab39a 100644 --- a/drivers/acpi/acpica/dbobject.c +++ b/drivers/acpi/acpica/dbobject.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c index 99fb0160b8fb..d6aaef54e369 100644 --- a/drivers/acpi/acpica/dbstats.c +++ b/drivers/acpi/acpica/dbstats.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbtest.c b/drivers/acpi/acpica/dbtest.c index c6bee6143266..56e446b89d18 100644 --- a/drivers/acpi/acpica/dbtest.c +++ b/drivers/acpi/acpica/dbtest.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbutils.c b/drivers/acpi/acpica/dbutils.c index bfa972b64171..cd40854ee9be 100644 --- a/drivers/acpi/acpica/dbutils.c +++ b/drivers/acpi/acpica/dbutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c index b6985323e7eb..77bbfa97cf91 100644 --- a/drivers/acpi/acpica/dbxface.c +++ b/drivers/acpi/acpica/dbxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index 2873455c986d..04a9f60e7ad1 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c index f470e81b0499..606697e741a5 100644 --- a/drivers/acpi/acpica/dscontrol.c +++ b/drivers/acpi/acpica/dscontrol.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -118,6 +118,8 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, control_state->control.package_end = walk_state->parser_state.pkg_end; control_state->control.opcode = op->common.aml_opcode; + control_state->control.loop_timeout = acpi_os_get_timer() + + (u64)(acpi_gbl_max_loop_iterations * ACPI_100NSEC_PER_SEC); /* Push the control state on this walk's control stack */ @@ -206,15 +208,15 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state, /* Predicate was true, the body of the loop was just executed */ /* - * This loop counter mechanism allows the interpreter to escape - * possibly infinite loops. This can occur in poorly written AML - * when the hardware does not respond within a while loop and the - * loop does not implement a timeout. + * This infinite loop detection mechanism allows the interpreter + * to escape possibly infinite loops. This can occur in poorly + * written AML when the hardware does not respond within a while + * loop and the loop does not implement a timeout. */ - control_state->control.loop_count++; - if (control_state->control.loop_count > - acpi_gbl_max_loop_iterations) { - status = AE_AML_INFINITE_LOOP; + if (ACPI_TIME_AFTER(acpi_os_get_timer(), + control_state->control. + loop_timeout)) { + status = AE_AML_LOOP_TIMEOUT; break; } diff --git a/drivers/acpi/acpica/dsdebug.c b/drivers/acpi/acpica/dsdebug.c index d1f457eda980..14ec52eba408 100644 --- a/drivers/acpi/acpica/dsdebug.c +++ b/drivers/acpi/acpica/dsdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 7bcf5f5ea029..95ea639a9424 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -209,7 +209,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.string, status); return_ACPI_STATUS(status); } } @@ -383,7 +384,9 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, walk_state, &info->connection_node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(child->common. + ACPI_ERROR_NAMESPACE(walk_state-> + scope_info, + child->common. value.name, status); return_ACPI_STATUS(status); @@ -402,7 +405,8 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, ACPI_NS_DONT_OPEN_SCOPE, walk_state, &info->field_node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE((char *)&arg->named.name, + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + (char *)&arg->named.name, status); return_ACPI_STATUS(status); } else { @@ -498,7 +502,8 @@ acpi_ds_create_field(union acpi_parse_object *op, ®ion_node); #endif if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.name, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.name, status); return_ACPI_STATUS(status); } } @@ -618,7 +623,8 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, ACPI_IMODE_LOAD_PASS1, flags, walk_state, &node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE((char *)&arg->named.name, + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + (char *)&arg->named.name, status); if (status != AE_ALREADY_EXISTS) { return_ACPI_STATUS(status); @@ -681,7 +687,8 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ®ion_node); #endif if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.name, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.name, status); return_ACPI_STATUS(status); } } @@ -695,7 +702,8 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.string, status); return_ACPI_STATUS(status); } @@ -765,7 +773,8 @@ acpi_ds_create_index_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.string, status); return_ACPI_STATUS(status); } @@ -778,7 +787,8 @@ acpi_ds_create_index_field(union acpi_parse_object *op, ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.string, status); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index b1842dd4edf7..946ff2e130d9 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index d7fc36917c67..b9c460c2d763 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 27a7de95f7b0..157f1645d91a 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 82448551781b..4fa3400a95ba 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -112,7 +112,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, acpi_namespace_node, &(op->common.node))); if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(op->common.value. + ACPI_ERROR_NAMESPACE(walk_state-> + scope_info, + op->common.value. string, status); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 0336df7ac47d..0181cd317751 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dspkginit.c b/drivers/acpi/acpica/dspkginit.c index 6d487edfe2de..902bee78036c 100644 --- a/drivers/acpi/acpica/dspkginit.c +++ b/drivers/acpi/acpica/dspkginit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -297,8 +297,10 @@ acpi_ds_init_package_element(u8 object_type, { union acpi_operand_object **element_ptr; + ACPI_FUNCTION_TRACE(ds_init_package_element); + if (!source_object) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -329,7 +331,7 @@ acpi_ds_init_package_element(u8 object_type, source_object->package.flags |= AOPOBJ_DATA_VALID; } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /******************************************************************************* @@ -352,6 +354,7 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr) union acpi_generic_state scope_info; union acpi_operand_object *element = *element_ptr; struct acpi_namespace_node *resolved_node; + struct acpi_namespace_node *original_node; char *external_path = NULL; acpi_object_type type; @@ -441,6 +444,7 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr) * will remain as named references. This behavior is not described * in the ACPI spec, but it appears to be an oversight. */ + original_node = resolved_node; status = acpi_ex_resolve_node_to_value(&resolved_node, NULL); if (ACPI_FAILURE(status)) { return_VOID; @@ -468,26 +472,27 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr) */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_THERMAL: - - /* TBD: This may not be necesssary */ - - acpi_ut_add_reference(resolved_node->object); + case ACPI_TYPE_METHOD: break; case ACPI_TYPE_MUTEX: - case ACPI_TYPE_METHOD: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: + /* acpi_ex_resolve_node_to_value gave these an extra reference */ + + acpi_ut_remove_reference(original_node->object); break; default: /* * For all other types - the node was resolved to an actual - * operand object with a value, return the object + * operand object with a value, return the object. Remove + * a reference on the existing object. */ + acpi_ut_remove_reference(element); *element_ptr = (union acpi_operand_object *)resolved_node; break; } diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 0dabd9b95684..a4ce0b4a55a6 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -583,7 +583,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, } if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(name_string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + name_string, status); } } diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 20d7744b06ae..2c07d220a50f 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -134,7 +134,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, * object. Implicitly convert the argument if necessary. */ status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, - ACPI_STRTOUL_BASE16); + ACPI_IMPLICIT_CONVERSION); if (ACPI_FAILURE(status)) { goto cleanup; } diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index eaa859a89702..fa4ef9229e17 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -207,7 +207,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, } #endif if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(path, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, + status); return_ACPI_STATUS(status); } @@ -375,7 +376,8 @@ acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, } if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(path, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + path, status); return_ACPI_STATUS(status); } } diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index aad83ef5a4ec..3b1313ba60d0 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -184,11 +184,14 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, if (status == AE_NOT_FOUND) { status = AE_OK; } else { - ACPI_ERROR_NAMESPACE(buffer_ptr, + ACPI_ERROR_NAMESPACE(walk_state-> + scope_info, + buffer_ptr, status); } #else - ACPI_ERROR_NAMESPACE(buffer_ptr, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + buffer_ptr, status); #endif return_ACPI_STATUS(status); } @@ -343,7 +346,8 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, } if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(buffer_ptr, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + buffer_ptr, status); return_ACPI_STATUS(status); } @@ -719,7 +723,8 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) */ op->common.node = new_node; } else { - ACPI_ERROR_NAMESPACE(arg->common.value.string, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, + arg->common.value.string, status); } break; diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index 3e081983d2ee..8b5c3613c060 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index da111a1f5bfb..ee002d17526e 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index d3b6b314fa50..4b2b0b44a16b 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c index 0ce33b0f430c..012b80de1501 100644 --- a/drivers/acpi/acpica/evglock.c +++ b/drivers/acpi/acpica/evglock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 229382035550..410a3907c051 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -390,8 +390,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) struct acpi_gpe_handler_info *gpe_handler_info; u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u8 enabled_status_byte; - u32 status_reg; - u32 enable_reg; + u64 status_reg; + u64 enable_reg; acpi_cpu_flags flags; u32 i; u32 j; @@ -472,7 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) gpe_register_info->base_gpe_number, gpe_register_info->base_gpe_number + (ACPI_GPE_REGISTER_WIDTH - 1), - status_reg, enable_reg, + (u32)status_reg, (u32)enable_reg, gpe_register_info->enable_for_run, gpe_register_info->enable_for_wake)); diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 3a3cb8624f41..7ce756cc28ab 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 8649c6242478..8ad4816c9950 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index c8adb400330a..729a8960a3af 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index 2db61ef1b4a3..20fb51c06b8d 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 4f6bb3f016ab..40d0b1f541a0 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 28b447ff92df..de196c8e3f30 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -298,6 +298,16 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. space_id))); + + /* + * Special case for an EC timeout. These are seen so frequently + * that an additional error message is helpful + */ + if ((region_obj->region.space_id == ACPI_ADR_SPACE_EC) && + (status == AE_TIME)) { + ACPI_ERROR((AE_INFO, + "Timeout from EC hardware or EC device driver")); + } } if (!(handler_desc->address_space.handler_flags & diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 93ec528bcd9a..4187f563fede 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 8ce73b962006..d5594f79f877 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index dd1b9dd64cef..9b3c01bf1438 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index c773ac4892cb..96c2520f9570 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 67c7c4ce276c..cbb1598df9dc 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index beba9d56a0d8..705fcd86151a 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconcat.c b/drivers/acpi/acpica/exconcat.c index 76bfb7dcae2f..ea20e10dd1f2 100644 --- a/drivers/acpi/acpica/exconcat.c +++ b/drivers/acpi/acpica/exconcat.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -156,7 +156,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, status = acpi_ex_convert_to_integer(local_operand1, &temp_operand1, - ACPI_STRTOUL_BASE16); + ACPI_IMPLICIT_CONVERSION); break; case ACPI_TYPE_BUFFER: diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 61813bd43f9e..827f47b72663 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index f71028e334ee..9abcc41a573b 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,10 +57,10 @@ acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); * * FUNCTION: acpi_ex_convert_to_integer * - * PARAMETERS: obj_desc - Object to be converted. Must be an - * Integer, Buffer, or String - * result_desc - Where the new Integer object is returned - * flags - Used for string conversion + * PARAMETERS: obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * result_desc - Where the new Integer object is returned + * implicit_conversion - Used for string conversion * * RETURN: Status * @@ -70,14 +70,14 @@ acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); acpi_status acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, u32 flags) + union acpi_operand_object **result_desc, + u32 implicit_conversion) { union acpi_operand_object *return_desc; u8 *pointer; u64 result; u32 i; u32 count; - acpi_status status; ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); @@ -123,12 +123,18 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, * hexadecimal as per the ACPI specification. The only exception (as * of ACPI 3.0) is that the to_integer() operator allows both decimal * and hexadecimal strings (hex prefixed with "0x"). + * + * Explicit conversion is used only by to_integer. + * All other string-to-integer conversions are implicit conversions. */ - status = acpi_ut_strtoul64(ACPI_CAST_PTR(char, pointer), - (acpi_gbl_integer_byte_width | - flags), &result); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + if (implicit_conversion) { + result = + acpi_ut_implicit_strtoul64(ACPI_CAST_PTR + (char, pointer)); + } else { + result = + acpi_ut_explicit_strtoul64(ACPI_CAST_PTR + (char, pointer)); } break; @@ -631,7 +637,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, */ status = acpi_ex_convert_to_integer(source_desc, result_desc, - ACPI_STRTOUL_BASE16); + ACPI_IMPLICIT_CONVERSION); break; case ACPI_TYPE_STRING: diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index b8adb11f1b07..3dece45dd997 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index a8191d2ca5e3..d931a66a16e3 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 83398dc4b7c2..4989ce9591ae 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -617,10 +617,11 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) u32 length; u32 index; - ACPI_FUNCTION_NAME(ex_dump_operand) + ACPI_FUNCTION_NAME(ex_dump_operand); - /* Check if debug output enabled */ - if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_EXEC, _COMPONENT)) { + /* Check if debug output enabled */ + + if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_EXEC, _COMPONENT)) { return; } @@ -904,7 +905,7 @@ void acpi_ex_dump_operands(union acpi_operand_object **operands, const char *opcode_name, u32 num_operands) { - ACPI_FUNCTION_NAME(ex_dump_operands); + ACPI_FUNCTION_TRACE(ex_dump_operands); if (!opcode_name) { opcode_name = "UNKNOWN"; @@ -928,7 +929,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** End operand dump for [%s]\n", opcode_name)); - return; + return_VOID; } /******************************************************************************* diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 5fda981f6498..e3b0650e5bb6 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index a656608dca84..3d0f274be88b 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 1e7649ce0a7b..1518fcb22ae1 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -330,7 +330,7 @@ acpi_ex_do_logical_op(u16 opcode, case ACPI_TYPE_INTEGER: status = acpi_ex_convert_to_integer(operand1, &local_operand1, - ACPI_STRTOUL_BASE16); + ACPI_IMPLICIT_CONVERSION); break; case ACPI_TYPE_STRING: diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index ecd95b3f35f1..24c9741dee48 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index caa5ed1f65ec..c7b249cda5c0 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index f787651348c1..dae01c93e480 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 57980b7d3594..3cafa1d6f31a 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index ce857addc8db..f16c655121ff 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 688032b58a21..8b39fffce6dc 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 8de060664204..1d1040f2e3f8 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 7bcc9d809b7e..387c438aa485 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 91c1de046442..77fa8d9aa5bf 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 5e1854ea85f6..b104bc3ca809 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index c4852429e2ff..2643d34f194d 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -415,7 +415,7 @@ acpi_ex_resolve_operands(u16 opcode, * Known as "Implicit Source Operand Conversion" */ status = acpi_ex_convert_to_integer(obj_desc, stack_ptr, - ACPI_STRTOUL_BASE16); + ACPI_IMPLICIT_CONVERSION); if (ACPI_FAILURE(status)) { if (status == AE_TYPE) { ACPI_ERROR((AE_INFO, diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index bdd43cde8f36..8f106bdcad5f 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 56f59cf5da29..3d458d1996b0 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 4ba7fcbf23b0..905443a3c28f 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index ad3b610057f3..420d9b145d2e 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/extrace.c b/drivers/acpi/acpica/extrace.c index ae9df8672d9e..9a67d507a132 100644 --- a/drivers/acpi/acpica/extrace.c +++ b/drivers/acpi/acpica/extrace.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 34d608358eaf..fb80d3f55d63 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index fad249e774b4..68e958d4c25f 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 12626d021a9b..64855b62a5ae 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 5eb11b30a79e..c1c54af148d0 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) { struct acpi_gpe_register_info *gpe_register_info; acpi_status status = AE_OK; - u32 enable_mask; + u64 enable_mask; u32 register_bit; ACPI_FUNCTION_ENTRY(); @@ -214,7 +214,7 @@ acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, acpi_event_status *event_status) { - u32 in_byte; + u64 in_byte; u32 register_bit; struct acpi_gpe_register_info *gpe_register_info; acpi_event_status local_event_status = 0; diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index 283819930be6..faa2fa45eb1c 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index acb417b58bbb..f3e7b7851a3a 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -220,16 +220,15 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, * * RETURN: Status * - * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max - * version of acpi_read, used internally since the overhead of - * 64-bit values is not needed. + * DESCRIPTION: Read from either memory or IO space. This is a 64-bit max + * version of acpi_read. * * LIMITATIONS: <These limitations also apply to acpi_hw_write> * space_ID must be system_memory or system_IO. * ******************************************************************************/ -acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) +acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg) { u64 address; u8 access_width; @@ -244,17 +243,17 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) /* Validate contents of the GAS register */ - status = acpi_hw_validate_register(reg, 32, &address); + status = acpi_hw_validate_register(reg, 64, &address); if (ACPI_FAILURE(status)) { return (status); } /* - * Initialize entire 32-bit return value to zero, convert access_width + * Initialize entire 64-bit return value to zero, convert access_width * into number of bits based */ *value = 0; - access_width = acpi_hw_get_access_bit_width(address, reg, 32); + access_width = acpi_hw_get_access_bit_width(address, reg, 64); bit_width = reg->bit_offset + reg->bit_width; bit_offset = reg->bit_offset; @@ -265,7 +264,7 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) index = 0; while (bit_width) { if (bit_offset >= access_width) { - value32 = 0; + value64 = 0; bit_offset -= access_width; } else { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { @@ -276,7 +275,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) ACPI_DIV_8 (access_width), &value64, access_width); - value32 = (u32)value64; } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_read_port((acpi_io_address) @@ -286,15 +284,16 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) (access_width), &value32, access_width); + value64 = (u64)value32; } } /* * Use offset style bit writes because "Index * AccessWidth" is - * ensured to be less than 32-bits by acpi_hw_validate_register(). + * ensured to be less than 64-bits by acpi_hw_validate_register(). */ ACPI_SET_BITS(value, index * access_width, - ACPI_MASK_BITS_ABOVE_32(access_width), value32); + ACPI_MASK_BITS_ABOVE_64(access_width), value64); bit_width -= bit_width > access_width ? access_width : bit_width; @@ -302,8 +301,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) } ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *value, access_width, ACPI_FORMAT_UINT64(address), + "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64(*value), access_width, + ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); @@ -318,20 +318,18 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) * * RETURN: Status * - * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max - * version of acpi_write, used internally since the overhead of - * 64-bit values is not needed. + * DESCRIPTION: Write to either memory or IO space. This is a 64-bit max + * version of acpi_write. * ******************************************************************************/ -acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) +acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg) { u64 address; u8 access_width; u32 bit_width; u8 bit_offset; u64 value64; - u32 value32; u8 index; acpi_status status; @@ -339,14 +337,14 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) /* Validate contents of the GAS register */ - status = acpi_hw_validate_register(reg, 32, &address); + status = acpi_hw_validate_register(reg, 64, &address); if (ACPI_FAILURE(status)) { return (status); } /* Convert access_width into number of bits based */ - access_width = acpi_hw_get_access_bit_width(address, reg, 32); + access_width = acpi_hw_get_access_bit_width(address, reg, 64); bit_width = reg->bit_offset + reg->bit_width; bit_offset = reg->bit_offset; @@ -358,16 +356,15 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) while (bit_width) { /* * Use offset style bit reads because "Index * AccessWidth" is - * ensured to be less than 32-bits by acpi_hw_validate_register(). + * ensured to be less than 64-bits by acpi_hw_validate_register(). */ - value32 = ACPI_GET_BITS(&value, index * access_width, - ACPI_MASK_BITS_ABOVE_32(access_width)); + value64 = ACPI_GET_BITS(&value, index * access_width, + ACPI_MASK_BITS_ABOVE_64(access_width)); if (bit_offset >= access_width) { bit_offset -= access_width; } else { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - value64 = (u64)value32; status = acpi_os_write_memory((acpi_physical_address) address + @@ -382,7 +379,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) index * ACPI_DIV_8 (access_width), - value32, + (u32)value64, access_width); } } @@ -397,8 +394,9 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) } ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - value, access_width, ACPI_FORMAT_UINT64(address), + "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64(value), access_width, + ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); @@ -526,6 +524,7 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) { u32 value = 0; + u64 value64; acpi_status status; ACPI_FUNCTION_TRACE(hw_register_read); @@ -564,12 +563,14 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ status = - acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); + acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block); + value = (u32)value64; break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block); + value = (u32)value64; break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ @@ -586,7 +587,7 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) } if (ACPI_SUCCESS(status)) { - *return_value = value; + *return_value = (u32)value; } return_ACPI_STATUS(status); @@ -622,6 +623,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) { acpi_status status; u32 read_value; + u64 read_value64; ACPI_FUNCTION_TRACE(hw_register_write); @@ -685,11 +687,12 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) * as per the ACPI spec. */ status = - acpi_hw_read(&read_value, + acpi_hw_read(&read_value64, &acpi_gbl_FADT.xpm2_control_block); if (ACPI_FAILURE(status)) { goto exit; } + read_value = (u32)read_value64; /* Insert the bits to be preserved */ @@ -745,22 +748,25 @@ acpi_hw_read_multiple(u32 *value, { u32 value_a = 0; u32 value_b = 0; + u64 value64; acpi_status status; /* The first register is always required */ - status = acpi_hw_read(&value_a, register_a); + status = acpi_hw_read(&value64, register_a); if (ACPI_FAILURE(status)) { return (status); } + value_a = (u32)value64; /* Second register is optional */ if (register_b->address) { - status = acpi_hw_read(&value_b, register_b); + status = acpi_hw_read(&value64, register_b); if (ACPI_FAILURE(status)) { return (status); } + value_b = (u32)value64; } /* diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 1fe7387a00e6..c85c373ecbc4 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b3c5d8c754bb..511e3b8ffc6d 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,6 +94,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution) acpi_status acpi_get_timer(u32 * ticks) { acpi_status status; + u64 timer_value; ACPI_FUNCTION_TRACE(acpi_get_timer); @@ -107,7 +108,14 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(AE_SUPPORT); } - status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_read(&timer_value, &acpi_gbl_FADT.xpm_timer_block); + if (ACPI_SUCCESS(status)) { + + /* ACPI PM Timer is defined to be 32 bits (PM_TMR_LEN) */ + + *ticks = (u32)timer_value; + } + return_ACPI_STATUS(status); } @@ -142,10 +150,10 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer) * ******************************************************************************/ acpi_status -acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) +acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 *time_elapsed) { acpi_status status; - u32 delta_ticks; + u64 delta_ticks; u64 quotient; ACPI_FUNCTION_TRACE(acpi_get_timer_duration); @@ -160,30 +168,29 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) return_ACPI_STATUS(AE_SUPPORT); } + if (start_ticks == end_ticks) { + *time_elapsed = 0; + return_ACPI_STATUS(AE_OK); + } + /* * Compute Tick Delta: * Handle (max one) timer rollovers on 24-bit versus 32-bit timers. */ - if (start_ticks < end_ticks) { - delta_ticks = end_ticks - start_ticks; - } else if (start_ticks > end_ticks) { + delta_ticks = end_ticks; + if (start_ticks > end_ticks) { if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { /* 24-bit Timer */ - delta_ticks = - (((0x00FFFFFF - start_ticks) + - end_ticks) & 0x00FFFFFF); + delta_ticks |= (u64)1 << 24; } else { /* 32-bit Timer */ - delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks; + delta_ticks |= (u64)1 << 32; } - } else { /* start_ticks == end_ticks */ - - *time_elapsed = 0; - return_ACPI_STATUS(AE_OK); } + delta_ticks -= start_ticks; /* * Compute Duration (Requires a 64-bit multiply and divide): @@ -191,10 +198,10 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) * time_elapsed (microseconds) = * (delta_ticks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY; */ - status = acpi_ut_short_divide(((u64)delta_ticks) * ACPI_USEC_PER_SEC, + status = acpi_ut_short_divide(delta_ticks * ACPI_USEC_PER_SEC, ACPI_PM_TIMER_FREQUENCY, "ient, NULL); - *time_elapsed = (u32) quotient; + *time_elapsed = (u32)quotient; return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index 3094cec4eab4..65d82e6add0b 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -128,14 +128,14 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) acpi_io_address last_address; const struct acpi_port_info *port_info; - ACPI_FUNCTION_NAME(hw_validate_io_request); + ACPI_FUNCTION_TRACE(hw_validate_io_request); /* Supported widths are 8/16/32 */ if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) { ACPI_ERROR((AE_INFO, "Bad BitWidth parameter: %8.8X", bit_width)); - return (AE_BAD_PARAMETER); + return_ACPI_STATUS(AE_BAD_PARAMETER); } port_info = acpi_protected_ports; @@ -153,13 +153,13 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ACPI_ERROR((AE_INFO, "Illegal I/O port address/length above 64K: %8.8X%8.8X/0x%X", ACPI_FORMAT_UINT64(address), byte_width)); - return (AE_LIMIT); + return_ACPI_STATUS(AE_LIMIT); } /* Exit if requested address is not within the protected port table */ if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* Check request against the list of protected I/O ports */ @@ -180,8 +180,8 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) /* Port illegality may depend on the _OSI calls made by the BIOS */ if (acpi_gbl_osi_data >= port_info->osi_dependency) { - ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)", + ACPI_DEBUG_PRINT((ACPI_DB_VALUES, + "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n", ACPI_FORMAT_UINT64(address), byte_width, port_info->name, port_info->start, @@ -198,7 +198,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) } } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 34684ae89981..d320b129b7d7 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -125,76 +125,12 @@ ACPI_EXPORT_SYMBOL(acpi_reset) ******************************************************************************/ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) { - u32 value_lo; - u32 value_hi; - u32 width; - u64 address; acpi_status status; ACPI_FUNCTION_NAME(acpi_read); - if (!return_value) { - return (AE_BAD_PARAMETER); - } - - /* Validate contents of the GAS register. Allow 64-bit transfers */ - - status = acpi_hw_validate_register(reg, 64, &address); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * Two address spaces supported: Memory or I/O. PCI_Config is - * not supported here because the GAS structure is insufficient - */ - if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - status = acpi_os_read_memory((acpi_physical_address) - address, return_value, - reg->bit_width); - if (ACPI_FAILURE(status)) { - return (status); - } - } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ - - value_lo = 0; - value_hi = 0; - - width = reg->bit_width; - if (width == 64) { - width = 32; /* Break into two 32-bit transfers */ - } - - status = acpi_hw_read_port((acpi_io_address) - address, &value_lo, width); - if (ACPI_FAILURE(status)) { - return (status); - } - - if (reg->bit_width == 64) { - - /* Read the top 32 bits */ - - status = acpi_hw_read_port((acpi_io_address) - (address + 4), &value_hi, - 32); - if (ACPI_FAILURE(status)) { - return (status); - } - } - - /* Set the return value only if status is AE_OK */ - - *return_value = (value_lo | ((u64)value_hi << 32)); - } - - ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", - ACPI_FORMAT_UINT64(*return_value), reg->bit_width, - ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); - - return (AE_OK); + status = acpi_hw_read(return_value, reg); + return (status); } ACPI_EXPORT_SYMBOL(acpi_read) @@ -213,59 +149,11 @@ ACPI_EXPORT_SYMBOL(acpi_read) ******************************************************************************/ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) { - u32 width; - u64 address; acpi_status status; ACPI_FUNCTION_NAME(acpi_write); - /* Validate contents of the GAS register. Allow 64-bit transfers */ - - status = acpi_hw_validate_register(reg, 64, &address); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* - * Two address spaces supported: Memory or IO. PCI_Config is - * not supported here because the GAS structure is insufficient - */ - if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - status = acpi_os_write_memory((acpi_physical_address) - address, value, reg->bit_width); - if (ACPI_FAILURE(status)) { - return (status); - } - } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ - - width = reg->bit_width; - if (width == 64) { - width = 32; /* Break into two 32-bit transfers */ - } - - status = acpi_hw_write_port((acpi_io_address) - address, ACPI_LODWORD(value), - width); - if (ACPI_FAILURE(status)) { - return (status); - } - - if (reg->bit_width == 64) { - status = acpi_hw_write_port((acpi_io_address) - (address + 4), - ACPI_HIDWORD(value), 32); - if (ACPI_FAILURE(status)) { - return (status); - } - } - } - - ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", - ACPI_FORMAT_UINT64(value), reg->bit_width, - ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(reg->space_id))); - + status = acpi_hw_write(value, reg); return (status); } diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index e5c095ca6083..589c774bbf9a 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index f2733f51ca8d..07f672b5a1d1 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -644,17 +644,18 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, this_node->object; } } -#ifdef ACPI_ASL_COMPILER - if (!acpi_gbl_disasm_flag && - (this_node->flags & ANOBJ_IS_EXTERNAL)) { - this_node->flags |= IMPLICIT_EXTERNAL; - } -#endif } /* Special handling for the last segment (num_segments == 0) */ else { +#ifdef ACPI_ASL_COMPILER + if (!acpi_gbl_disasm_flag + && (this_node->flags & ANOBJ_IS_EXTERNAL)) { + this_node->flags &= ~IMPLICIT_EXTERNAL; + } +#endif + /* * Sanity typecheck of the target object: * diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 8ba5b32c9f71..ce57ccf4c1bf 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsarguments.c b/drivers/acpi/acpica/nsarguments.c index 67b7370dcae5..ce296ac14cf0 100644 --- a/drivers/acpi/acpica/nsarguments.c +++ b/drivers/acpi/acpica/nsarguments.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index e4a7da8a11f0..2f9d5d190fa9 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -78,8 +78,8 @@ acpi_ns_convert_to_integer(union acpi_operand_object *original_object, /* String-to-Integer conversion */ - status = acpi_ut_strtoul64(original_object->string.pointer, - acpi_gbl_integer_byte_width, &value); + status = + acpi_ut_strtoul64(original_object->string.pointer, &value); if (ACPI_FAILURE(status)) { return (status); } @@ -495,7 +495,8 @@ acpi_ns_convert_to_reference(struct acpi_namespace_node *scope, /* Check if we are resolving a named reference within a package */ - ACPI_ERROR_NAMESPACE(original_object->string.pointer, status); + ACPI_ERROR_NAMESPACE(&scope_info, + original_object->string.pointer, status); goto error_exit; } diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 4123b5077a7d..e2ac16818dc3 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 5026594763ea..09ac00dee450 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index d22167cbd0ca..c2d883b8c45e 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 9c6297949712..c17af4a3ab67 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index d2915e186ae1..fdfe9309bd33 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index a410760a0308..c686eda7ca66 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,9 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames") +/* Local Prototypes */ +static void acpi_ns_normalize_pathname(char *original_path); + /******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname @@ -63,6 +66,7 @@ ACPI_MODULE_NAME("nsnames") * for error and debug statements. * ******************************************************************************/ + char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) { char *name_buffer; @@ -352,3 +356,148 @@ char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, return_PTR(name_buffer); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_build_prefixed_pathname + * + * PARAMETERS: prefix_scope - Scope/Path that prefixes the internal path + * internal_path - Name or path of the namespace node + * + * RETURN: None + * + * DESCRIPTION: Construct a fully qualified pathname from a concatenation of: + * 1) Path associated with the prefix_scope namespace node + * 2) External path representation of the Internal path + * + ******************************************************************************/ + +char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope, + const char *internal_path) +{ + acpi_status status; + char *full_path = NULL; + char *external_path = NULL; + char *prefix_path = NULL; + u32 prefix_path_length = 0; + + /* If there is a prefix, get the pathname to it */ + + if (prefix_scope && prefix_scope->scope.node) { + prefix_path = + acpi_ns_get_normalized_pathname(prefix_scope->scope.node, + TRUE); + if (prefix_path) { + prefix_path_length = strlen(prefix_path); + } + } + + status = acpi_ns_externalize_name(ACPI_UINT32_MAX, internal_path, + NULL, &external_path); + if (ACPI_FAILURE(status)) { + goto cleanup; + } + + /* Merge the prefix path and the path. 2 is for one dot and trailing null */ + + full_path = + ACPI_ALLOCATE_ZEROED(prefix_path_length + strlen(external_path) + + 2); + if (!full_path) { + goto cleanup; + } + + /* Don't merge if the External path is already fully qualified */ + + if (prefix_path && (*external_path != '\\') && (*external_path != '^')) { + strcat(full_path, prefix_path); + if (prefix_path[1]) { + strcat(full_path, "."); + } + } + + acpi_ns_normalize_pathname(external_path); + strcat(full_path, external_path); + +cleanup: + if (prefix_path) { + ACPI_FREE(prefix_path); + } + if (external_path) { + ACPI_FREE(external_path); + } + + return (full_path); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_normalize_pathname + * + * PARAMETERS: original_path - Path to be normalized, in External format + * + * RETURN: The original path is processed in-place + * + * DESCRIPTION: Remove trailing underscores from each element of a path. + * + * For example: \A___.B___.C___ becomes \A.B.C + * + ******************************************************************************/ + +static void acpi_ns_normalize_pathname(char *original_path) +{ + char *input_path = original_path; + char *new_path_buffer; + char *new_path; + u32 i; + + /* Allocate a temp buffer in which to construct the new path */ + + new_path_buffer = ACPI_ALLOCATE_ZEROED(strlen(input_path) + 1); + new_path = new_path_buffer; + if (!new_path_buffer) { + return; + } + + /* Special characters may appear at the beginning of the path */ + + if (*input_path == '\\') { + *new_path = *input_path; + new_path++; + input_path++; + } + + while (*input_path == '^') { + *new_path = *input_path; + new_path++; + input_path++; + } + + /* Remainder of the path */ + + while (*input_path) { + + /* Do one nameseg at a time */ + + for (i = 0; (i < ACPI_NAME_SIZE) && *input_path; i++) { + if ((i == 0) || (*input_path != '_')) { /* First char is allowed to be underscore */ + *new_path = *input_path; + new_path++; + } + + input_path++; + } + + /* Dot means that there are more namesegs to come */ + + if (*input_path == '.') { + *new_path = *input_path; + new_path++; + input_path++; + } + } + + *new_path = 0; + strcpy(original_path, new_path_buffer); + ACPI_FREE(new_path_buffer); +} diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 707b2aa501e1..757e44555ec3 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 2fc33a5203f4..c5b22ea5b369 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 9d14b509529e..4f1f6d6d9ddf 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index a8ea8fb1d299..7805d5ce8127 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 418ef2ac82ab..7b6b6d281f1c 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 06037e044694..29c3973c7815 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 5de8957f5ef0..a469447f5c02 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -417,6 +417,7 @@ acpi_ns_search_and_enter(u32 target_name, if (flags & ACPI_NS_EXTERNAL || (walk_state && walk_state->opcode == AML_SCOPE_OP)) { new_node->flags |= ANOBJ_IS_EXTERNAL; + new_node->flags |= IMPLICIT_EXTERNAL; } #endif diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index b43fe5fce64b..0487fdb59b0e 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 6b6e6f498cff..dd7ae1bc8af8 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 783f4c838aee..1075bd9541f5 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,10 +61,10 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); * * PARAMETERS: handle - Object handle (optional) * pathname - Object pathname (optional) - * external_params - List of parameters to pass to method, + * external_params - List of parameters to pass to a method, * terminated by NULL. May be NULL * if no parameters are being passed. - * return_buffer - Where to put method's return value (if + * return_buffer - Where to put the object's return value (if * any). If NULL, no value is returned. * return_type - Expected type of return object * @@ -100,13 +100,14 @@ acpi_evaluate_object_typed(acpi_handle handle, free_buffer_on_error = TRUE; } + /* Get a handle here, in order to build an error message if needed */ + + target_handle = handle; if (pathname) { status = acpi_get_handle(handle, pathname, &target_handle); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - } else { - target_handle = handle; } full_pathname = acpi_ns_get_external_pathname(target_handle); diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 106966235805..e9603fc9586c 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 47f689ec3fcb..ac1fbf767cac 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index eb9dfaca555f..dbc51bc5fdd6 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -361,7 +361,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, /* Final exception check (may have been changed from code above) */ if (ACPI_FAILURE(status)) { - ACPI_ERROR_NAMESPACE(path, status); + ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status); if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index bb04dec168ad..7dca287d7690 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index 0bef6df71bba..b18f1e048985 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -372,16 +372,10 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, * external declaration opcode. Setting walk_state->Aml to * walk_state->parser_state.Aml + 2 moves increments the * walk_state->Aml past the object type and the paramcount of the - * external opcode. For the error message, only print the AML - * offset. We could attempt to print the name but this may cause - * a segmentation fault when printing the namepath because the - * AML may be incorrect. + * external opcode. */ - acpi_os_printf - ("// Invalid external declaration at AML offset 0x%x.\n", - walk_state->aml - - walk_state->parser_state.aml_start); walk_state->aml = walk_state->parser_state.aml + 2; + walk_state->parser_state.aml = walk_state->aml; return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); } #endif diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index a402ad772a1e..d31f3eb23225 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psopinfo.c b/drivers/acpi/acpica/psopinfo.c index eff22950232b..1dc1fc79297e 100644 --- a/drivers/acpi/acpica/psopinfo.c +++ b/drivers/acpi/acpica/psopinfo.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index ac88319dc111..2474ff961294 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 22d7f1d6849b..f49cdcc65700 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index c06d6e2fc7a5..f9fa88c79b32 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 02642760cb93..fe151f42de3a 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,9 +94,11 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) op->common.descriptor_type = ACPI_DESC_TYPE_PARSER; op->common.aml_opcode = opcode; - ACPI_DISASM_ONLY_MEMBERS(strncpy(op->common.aml_op_name, - (acpi_ps_get_opcode_info(opcode))-> - name, sizeof(op->common.aml_op_name))); + ACPI_DISASM_ONLY_MEMBERS(acpi_ut_safe_strncpy(op->common.aml_op_name, + (acpi_ps_get_opcode_info + (opcode))->name, + sizeof(op->common. + aml_op_name))); } /******************************************************************************* @@ -158,10 +160,10 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode, u8 *aml) if (opcode == AML_SCOPE_OP) { acpi_gbl_current_scope = op; } - } - if (gbl_capture_comments) { - ASL_CV_TRANSFER_COMMENTS(op); + if (acpi_gbl_capture_comments) { + ASL_CV_TRANSFER_COMMENTS(op); + } } return (op); diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 22a37c82af19..bc5c779e54e8 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index c88a681586bf..d2270ade5cf8 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index a131a28bb09d..213bad89675b 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 659fb718504a..576f7aae162b 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index f72ff0b54a63..fe07001ea865 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index 55fd1880efbe..bc4c4755aeb9 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsdumpinfo.c b/drivers/acpi/acpica/rsdumpinfo.c index da150e17795b..c4a2a08e31ac 100644 --- a/drivers/acpi/acpica/rsdumpinfo.c +++ b/drivers/acpi/acpica/rsdumpinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index b0e50518d766..e819bb0f45af 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index b7a47fbc519b..eafd993592f6 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 092a733c42b8..aabd73298eb8 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 36a6657dd34d..11214780ea8f 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index 273eecb3001b..05e375abc6b5 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index cc4b5486c4bc..7b4627181cc6 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsserial.c b/drivers/acpi/acpica/rsserial.c index 14d12d6eb716..87dac2812072 100644 --- a/drivers/acpi/acpica/rsserial.c +++ b/drivers/acpi/acpica/rsserial.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index b2aeca01204a..49ff7f851d58 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index be65e65e216e..3b481f0b81c5 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index b19a2f0ea331..ec69267f1447 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 5f051d82188d..d1763c5e4e91 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index fea89c8d305c..999a64a48e1a 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 0dfc0ac3c141..00be16da1ee2 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index edfd7b10be19..8cdcdd2c4697 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 0c6768d20395..30d40ff8992b 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 26ad596c973e..dca91b6f8cc2 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -173,10 +173,13 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); /* - * Only reallocate the root table if the host provided a static buffer - * for the table array in the call to acpi_initialize_tables. + * If there are tables unverified, it is required to reallocate the + * root table list to clean up invalid table entries. Otherwise only + * reallocate the root table list if the host provided a static buffer + * for the table array in the call to acpi_initialize_tables(). */ - if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { + if ((acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) && + acpi_gbl_enable_table_validation) { return_ACPI_STATUS(AE_SUPPORT); } diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index d81f442228b8..e09b4b26300e 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index f9f9a7da2cad..abf3c62e1e80 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index 26a0633115be..d8540f380ae5 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 5594a359dbf1..12fbaddbfb0d 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utascii.c b/drivers/acpi/acpica/utascii.c index 909bdb198651..95565e46a695 100644 --- a/drivers/acpi/acpica/utascii.c +++ b/drivers/acpi/acpica/utascii.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index f17eaa009dde..2c5a14c2f46b 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index 531493306dee..08e6944404b3 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index e9382255d6c6..01434af99035 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 615a885e2ca3..2201be1bf4c2 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -163,6 +163,9 @@ acpi_debug_print(u32 requested_debug_level, { acpi_thread_id thread_id; va_list args; +#ifdef ACPI_APPLICATION + int fill_count; +#endif /* Check if debug output enabled */ @@ -202,10 +205,21 @@ acpi_debug_print(u32 requested_debug_level, acpi_os_printf("[%u] ", (u32)thread_id); } - acpi_os_printf("[%02ld] ", acpi_gbl_nesting_level); -#endif + fill_count = 48 - acpi_gbl_nesting_level - + strlen(acpi_ut_trim_function_name(function_name)); + if (fill_count < 0) { + fill_count = 0; + } + + acpi_os_printf("[%02ld] %*s", + acpi_gbl_nesting_level, acpi_gbl_nesting_level + 1, " "); + acpi_os_printf("%s%*s: ", + acpi_ut_trim_function_name(function_name), fill_count, + " "); +#else acpi_os_printf("%-22.22s: ", acpi_ut_trim_function_name(function_name)); +#endif va_start(args, format); acpi_os_vprintf(format, args); diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 02cd2c2d961a..1a3f316a18a8 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -395,11 +395,6 @@ const char *acpi_ut_get_reference_name(union acpi_operand_object *object) return (acpi_gbl_ref_class_names[object->reference.class]); } -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) -/* - * Strings and procedures used for debug only - */ - /******************************************************************************* * * FUNCTION: acpi_ut_get_mutex_name @@ -433,6 +428,12 @@ const char *acpi_ut_get_mutex_name(u32 mutex_id) return (acpi_gbl_mutex_names[mutex_id]); } +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + +/* + * Strings and procedures used for debug only + */ + /******************************************************************************* * * FUNCTION: acpi_ut_get_notify_name diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index c6eb9fae70f9..7d8d0208f0a3 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c index e3368186e1c1..ce5e891291bf 100644 --- a/drivers/acpi/acpica/uterror.c +++ b/drivers/acpi/acpica/uterror.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -182,6 +182,78 @@ acpi_ut_predefined_bios_error(const char *module_name, /******************************************************************************* * + * FUNCTION: acpi_ut_prefixed_namespace_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * prefix_scope - Scope/Path that prefixes the internal path + * internal_path - Name or path of the namespace node + * lookup_status - Exception code from NS lookup + * + * RETURN: None + * + * DESCRIPTION: Print error message with the full pathname constructed this way: + * + * prefix_scope_node_full_path.externalized_internal_path + * + * NOTE: 10/2017: Treat the major ns_lookup errors as firmware errors + * + ******************************************************************************/ + +void +acpi_ut_prefixed_namespace_error(const char *module_name, + u32 line_number, + union acpi_generic_state *prefix_scope, + const char *internal_path, + acpi_status lookup_status) +{ + char *full_path; + const char *message; + + /* + * Main cases: + * 1) Object creation, object must not already exist + * 2) Object lookup, object must exist + */ + switch (lookup_status) { + case AE_ALREADY_EXISTS: + + acpi_os_printf(ACPI_MSG_BIOS_ERROR); + message = "Failure creating"; + break; + + case AE_NOT_FOUND: + + acpi_os_printf(ACPI_MSG_BIOS_ERROR); + message = "Failure looking up"; + break; + + default: + + acpi_os_printf(ACPI_MSG_ERROR); + message = "Failure looking up"; + break; + } + + /* Concatenate the prefix path and the internal path */ + + full_path = + acpi_ns_build_prefixed_pathname(prefix_scope, internal_path); + + acpi_os_printf("%s [%s], %s", message, + full_path ? full_path : "Could not get pathname", + acpi_format_exception(lookup_status)); + + if (full_path) { + ACPI_FREE(full_path); + } + + ACPI_MSG_SUFFIX; +} + +#ifdef __OBSOLETE_FUNCTION +/******************************************************************************* + * * FUNCTION: acpi_ut_namespace_error * * PARAMETERS: module_name - Caller's module name (for error output) @@ -240,6 +312,7 @@ acpi_ut_namespace_error(const char *module_name, ACPI_MSG_SUFFIX; ACPI_MSG_REDIRECT_END; } +#endif /******************************************************************************* * diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 3fce7519c690..b8be0b82a130 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utexcep.c b/drivers/acpi/acpica/utexcep.c index eb6dcab33d2f..e3dbad8b73e5 100644 --- a/drivers/acpi/acpica/utexcep.c +++ b/drivers/acpi/acpica/utexcep.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 230a50c82f22..933595b0e594 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uthex.c b/drivers/acpi/acpica/uthex.c index fb406daf47fa..f5886d557a94 100644 --- a/drivers/acpi/acpica/uthex.c +++ b/drivers/acpi/acpica/uthex.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index a6eb580ee21d..db3c3c1d33da 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 23e766d1691d..a2005b030347 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -206,7 +206,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_next_owner_id_offset = 0; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_osi_mutex = NULL; - acpi_gbl_max_loop_iterations = ACPI_MAX_LOOP_COUNT; /* Hardware oriented */ diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index db2d9910866e..0636074a4c23 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 5f9c680076c4..eddf71990433 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -134,7 +134,7 @@ acpi_status acpi_ut_short_shift_left(u64 operand, u32 count, u64 *out_result) if ((count & 63) >= 32) { operand_ovl.part.hi = operand_ovl.part.lo; - operand_ovl.part.lo ^= operand_ovl.part.lo; + operand_ovl.part.lo = 0; count = (count & 63) - 32; } ACPI_SHIFT_LEFT_64_BY_32(operand_ovl.part.hi, @@ -171,7 +171,7 @@ acpi_status acpi_ut_short_shift_right(u64 operand, u32 count, u64 *out_result) if ((count & 63) >= 32) { operand_ovl.part.lo = operand_ovl.part.hi; - operand_ovl.part.hi ^= operand_ovl.part.hi; + operand_ovl.part.hi = 0; count = (count & 63) - 32; } ACPI_SHIFT_RIGHT_64_BY_32(operand_ovl.part.hi, diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 45c78c2adbf0..a331313ad5fa 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 586354788018..6767bd1626f7 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -286,8 +286,9 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, - "Thread %u could not acquire Mutex [0x%X]", - (u32)this_thread_id, mutex_id)); + "Thread %u could not acquire Mutex [%s] (0x%X)", + (u32)this_thread_id, + acpi_ut_get_mutex_name(mutex_id), mutex_id)); } return (status); @@ -322,8 +323,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) */ if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) { ACPI_ERROR((AE_INFO, - "Mutex [0x%X] is not acquired, cannot release", - mutex_id)); + "Mutex [%s] (0x%X) is not acquired, cannot release", + acpi_ut_get_mutex_name(mutex_id), mutex_id)); return (AE_NOT_ACQUIRED); } diff --git a/drivers/acpi/acpica/utnonansi.c b/drivers/acpi/acpica/utnonansi.c index 792664982ea3..94219610e259 100644 --- a/drivers/acpi/acpica/utnonansi.c +++ b/drivers/acpi/acpica/utnonansi.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -140,7 +140,7 @@ int acpi_ut_stricmp(char *string1, char *string2) return (c1 - c2); } -#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) +#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) || defined (ACPI_DEBUG_OUTPUT) /******************************************************************************* * * FUNCTION: acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat @@ -199,4 +199,13 @@ acpi_ut_safe_strncat(char *dest, strncat(dest, source, max_transfer_length); return (FALSE); } + +void acpi_ut_safe_strncpy(char *dest, char *source, acpi_size dest_size) +{ + /* Always terminate destination string */ + + strncpy(dest, source, dest_size); + dest[dest_size - 1] = 0; +} + #endif diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index cb3db9fed50d..375901c0a596 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 3175b133c0e4..00ea104f6a0a 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -101,6 +101,8 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */ {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */ {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */ + {"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1}, /* Windows 10 version 1607 - Added 12/2017 */ + {"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2}, /* Windows 10 version 1703 - Added 12/2017 */ /* Feature Group Strings */ diff --git a/drivers/acpi/acpica/utownerid.c b/drivers/acpi/acpica/utownerid.c index 1b3ee74a87eb..9923dfa708be 100644 --- a/drivers/acpi/acpica/utownerid.c +++ b/drivers/acpi/acpica/utownerid.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index 350709f23e4c..ae6fef02b692 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index c008589b41bd..ac07700f5b79 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresdecode.c b/drivers/acpi/acpica/utresdecode.c index e15a2538558b..93fa3450ca88 100644 --- a/drivers/acpi/acpica/utresdecode.c +++ b/drivers/acpi/acpica/utresdecode.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index f9801d13547f..4d289d9c734c 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index eafabcd2fada..7750c48739d8 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 9eacbcb9e4f4..a9507d1976ff 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstrsuppt.c b/drivers/acpi/acpica/utstrsuppt.c new file mode 100644 index 000000000000..6fc76f0b60e9 --- /dev/null +++ b/drivers/acpi/acpica/utstrsuppt.c @@ -0,0 +1,444 @@ +/******************************************************************************* + * + * Module Name: utstrsuppt - Support functions for string-to-integer conversion + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2018, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include <acpi/acpi.h> +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utstrsuppt") + +/* Local prototypes */ +static acpi_status +acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit); + +static acpi_status +acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product); + +static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_convert_octal_string + * + * PARAMETERS: string - Null terminated input string + * return_value_ptr - Where the converted value is returned + * + * RETURN: Status and 64-bit converted integer + * + * DESCRIPTION: Performs a base 8 conversion of the input string to an + * integer value, either 32 or 64 bits. + * + * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777 + * Maximum 32-bit unsigned octal value is 037777777777 + * + ******************************************************************************/ + +acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value_ptr) +{ + u64 accumulated_value = 0; + acpi_status status = AE_OK; + + /* Convert each ASCII byte in the input string */ + + while (*string) { + + /* Character must be ASCII 0-7, otherwise terminate with no error */ + + if (!(ACPI_IS_OCTAL_DIGIT(*string))) { + break; + } + + /* Convert and insert this octal digit into the accumulator */ + + status = acpi_ut_insert_digit(&accumulated_value, 8, *string); + if (ACPI_FAILURE(status)) { + status = AE_OCTAL_OVERFLOW; + break; + } + + string++; + } + + /* Always return the value that has been accumulated */ + + *return_value_ptr = accumulated_value; + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_convert_decimal_string + * + * PARAMETERS: string - Null terminated input string + * return_value_ptr - Where the converted value is returned + * + * RETURN: Status and 64-bit converted integer + * + * DESCRIPTION: Performs a base 10 conversion of the input string to an + * integer value, either 32 or 64 bits. + * + * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615 + * Maximum 32-bit unsigned decimal value is 4294967295 + * + ******************************************************************************/ + +acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr) +{ + u64 accumulated_value = 0; + acpi_status status = AE_OK; + + /* Convert each ASCII byte in the input string */ + + while (*string) { + + /* Character must be ASCII 0-9, otherwise terminate with no error */ + + if (!isdigit(*string)) { + break; + } + + /* Convert and insert this decimal digit into the accumulator */ + + status = acpi_ut_insert_digit(&accumulated_value, 10, *string); + if (ACPI_FAILURE(status)) { + status = AE_DECIMAL_OVERFLOW; + break; + } + + string++; + } + + /* Always return the value that has been accumulated */ + + *return_value_ptr = accumulated_value; + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_convert_hex_string + * + * PARAMETERS: string - Null terminated input string + * return_value_ptr - Where the converted value is returned + * + * RETURN: Status and 64-bit converted integer + * + * DESCRIPTION: Performs a base 16 conversion of the input string to an + * integer value, either 32 or 64 bits. + * + * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF + * Maximum 32-bit unsigned hex value is 0xFFFFFFFF + * + ******************************************************************************/ + +acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr) +{ + u64 accumulated_value = 0; + acpi_status status = AE_OK; + + /* Convert each ASCII byte in the input string */ + + while (*string) { + + /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */ + + if (!isxdigit(*string)) { + break; + } + + /* Convert and insert this hex digit into the accumulator */ + + status = acpi_ut_insert_digit(&accumulated_value, 16, *string); + if (ACPI_FAILURE(status)) { + status = AE_HEX_OVERFLOW; + break; + } + + string++; + } + + /* Always return the value that has been accumulated */ + + *return_value_ptr = accumulated_value; + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_leading_zeros + * + * PARAMETERS: string - Pointer to input ASCII string + * + * RETURN: Next character after any leading zeros. This character may be + * used by the caller to detect end-of-string. + * + * DESCRIPTION: Remove any leading zeros in the input string. Return the + * next character after the final ASCII zero to enable the caller + * to check for the end of the string (NULL terminator). + * + ******************************************************************************/ + +char acpi_ut_remove_leading_zeros(char **string) +{ + + while (**string == ACPI_ASCII_ZERO) { + *string += 1; + } + + return (**string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_whitespace + * + * PARAMETERS: string - Pointer to input ASCII string + * + * RETURN: Next character after any whitespace. This character may be + * used by the caller to detect end-of-string. + * + * DESCRIPTION: Remove any leading whitespace in the input string. Return the + * next character after the final ASCII zero to enable the caller + * to check for the end of the string (NULL terminator). + * + ******************************************************************************/ + +char acpi_ut_remove_whitespace(char **string) +{ + + while (isspace((u8)**string)) { + *string += 1; + } + + return (**string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_detect_hex_prefix + * + * PARAMETERS: string - Pointer to input ASCII string + * + * RETURN: TRUE if a "0x" prefix was found at the start of the string + * + * DESCRIPTION: Detect and remove a hex "0x" prefix + * + ******************************************************************************/ + +u8 acpi_ut_detect_hex_prefix(char **string) +{ + + if ((**string == ACPI_ASCII_ZERO) && + (tolower((int)*(*string + 1)) == 'x')) { + *string += 2; /* Go past the leading 0x */ + return (TRUE); + } + + return (FALSE); /* Not a hex string */ +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_detect_octal_prefix + * + * PARAMETERS: string - Pointer to input ASCII string + * + * RETURN: True if an octal "0" prefix was found at the start of the + * string + * + * DESCRIPTION: Detect and remove an octal prefix (zero) + * + ******************************************************************************/ + +u8 acpi_ut_detect_octal_prefix(char **string) +{ + + if (**string == ACPI_ASCII_ZERO) { + *string += 1; /* Go past the leading 0 */ + return (TRUE); + } + + return (FALSE); /* Not an octal string */ +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_insert_digit + * + * PARAMETERS: accumulated_value - Current value of the integer value + * accumulator. The new value is + * returned here. + * base - Radix, either 8/10/16 + * ascii_digit - ASCII single digit to be inserted + * + * RETURN: Status and result of the convert/insert operation. The only + * possible returned exception code is numeric overflow of + * either the multiply or add conversion operations. + * + * DESCRIPTION: Generic conversion and insertion function for all bases: + * + * 1) Multiply the current accumulated/converted value by the + * base in order to make room for the new character. + * + * 2) Convert the new character to binary and add it to the + * current accumulated value. + * + * Note: The only possible exception indicates an integer + * overflow (AE_NUMERIC_OVERFLOW) + * + ******************************************************************************/ + +static acpi_status +acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit) +{ + acpi_status status; + u64 product; + + /* Make room in the accumulated value for the incoming digit */ + + status = acpi_ut_strtoul_multiply64(*accumulated_value, base, &product); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Add in the new digit, and store the sum to the accumulated value */ + + status = + acpi_ut_strtoul_add64(product, + acpi_ut_ascii_char_to_hex(ascii_digit), + accumulated_value); + + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strtoul_multiply64 + * + * PARAMETERS: multiplicand - Current accumulated converted integer + * base - Base/Radix + * out_product - Where the product is returned + * + * RETURN: Status and 64-bit product + * + * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as + * well as 32-bit overflow if necessary (if the current global + * integer width is 32). + * + ******************************************************************************/ + +static acpi_status +acpi_ut_strtoul_multiply64(u64 multiplicand, u32 base, u64 *out_product) +{ + u64 product; + u64 quotient; + + /* Exit if either operand is zero */ + + *out_product = 0; + if (!multiplicand || !base) { + return (AE_OK); + } + + /* + * Check for 64-bit overflow before the actual multiplication. + * + * Notes: 64-bit division is often not supported on 32-bit platforms + * (it requires a library function), Therefore ACPICA has a local + * 64-bit divide function. Also, Multiplier is currently only used + * as the radix (8/10/16), to the 64/32 divide will always work. + */ + acpi_ut_short_divide(ACPI_UINT64_MAX, base, "ient, NULL); + if (multiplicand > quotient) { + return (AE_NUMERIC_OVERFLOW); + } + + product = multiplicand * base; + + /* Check for 32-bit overflow if necessary */ + + if ((acpi_gbl_integer_bit_width == 32) && (product > ACPI_UINT32_MAX)) { + return (AE_NUMERIC_OVERFLOW); + } + + *out_product = product; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strtoul_add64 + * + * PARAMETERS: addend1 - Current accumulated converted integer + * digit - New hex value/char + * out_sum - Where sum is returned (Accumulator) + * + * RETURN: Status and 64-bit sum + * + * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as + * well as 32-bit overflow if necessary (if the current global + * integer width is 32). + * + ******************************************************************************/ + +static acpi_status acpi_ut_strtoul_add64(u64 addend1, u32 digit, u64 *out_sum) +{ + u64 sum; + + /* Check for 64-bit overflow before the actual addition */ + + if ((addend1 > 0) && (digit > (ACPI_UINT64_MAX - addend1))) { + return (AE_NUMERIC_OVERFLOW); + } + + sum = addend1 + digit; + + /* Check for 32-bit overflow if necessary */ + + if ((acpi_gbl_integer_bit_width == 32) && (sum > ACPI_UINT32_MAX)) { + return (AE_NUMERIC_OVERFLOW); + } + + *out_sum = sum; + return (AE_OK); +} diff --git a/drivers/acpi/acpica/utstrtoul64.c b/drivers/acpi/acpica/utstrtoul64.c index 9633ee142855..9f7cef1de34a 100644 --- a/drivers/acpi/acpica/utstrtoul64.c +++ b/drivers/acpi/acpica/utstrtoul64.c @@ -1,11 +1,12 @@ /******************************************************************************* * - * Module Name: utstrtoul64 - string to 64-bit integer support + * Module Name: utstrtoul64 - String-to-integer conversion support for both + * 64-bit and 32-bit integers * ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,304 +45,319 @@ #include <acpi/acpi.h> #include "accommon.h" -/******************************************************************************* - * - * The functions in this module satisfy the need for 64-bit string-to-integer - * conversions on both 32-bit and 64-bit platforms. - * - ******************************************************************************/ - #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utstrtoul64") -/* Local prototypes */ -static u64 acpi_ut_strtoul_base10(char *string, u32 flags); - -static u64 acpi_ut_strtoul_base16(char *string, u32 flags); - /******************************************************************************* * - * String conversion rules as written in the ACPI specification. The error - * conditions and behavior are different depending on the type of conversion. - * - * - * Implicit data type conversion: string-to-integer - * -------------------------------------------------- - * - * Base is always 16. This is the ACPI_STRTOUL_BASE16 case. - * - * Example: - * Add ("BA98", Arg0, Local0) - * - * The integer is initialized to the value zero. - * The ASCII string is interpreted as a hexadecimal constant. + * This module contains the top-level string to 64/32-bit unsigned integer + * conversion functions: * - * 1) A "0x" prefix is not allowed. However, ACPICA allows this for - * compatibility with previous ACPICA. (NO ERROR) + * 1) A standard strtoul() function that supports 64-bit integers, base + * 8/10/16, with integer overflow support. This is used mainly by the + * iASL compiler, which implements tighter constraints on integer + * constants than the runtime (interpreter) integer-to-string conversions. + * 2) Runtime "Explicit conversion" as defined in the ACPI specification. + * 3) Runtime "Implicit conversion" as defined in the ACPI specification. * - * 2) Terminates when the size of an integer is reached (32 or 64 bits). - * (NO ERROR) + * Current users of this module: * - * 3) The first non-hex character terminates the conversion without error. - * (NO ERROR) - * - * 4) Conversion of a null (zero-length) string to an integer is not - * allowed. However, ACPICA allows this for compatibility with previous - * ACPICA. This conversion returns the value 0. (NO ERROR) - * - * - * Explicit data type conversion: to_integer() with string operand - * --------------------------------------------------------------- - * - * Base is either 10 (default) or 16 (with 0x prefix) - * - * Examples: - * to_integer ("1000") - * to_integer ("0xABCD") - * - * 1) Can be (must be) either a decimal or hexadecimal numeric string. - * A hex value must be prefixed by "0x" or it is interpreted as a decimal. + * iASL - Preprocessor (constants and math expressions) + * iASL - Main parser, conversion of constants to integers + * iASL - Data Table Compiler parser (constants and math expressions) + * interpreter - Implicit and explicit conversions, GPE method names + * interpreter - Repair code for return values from predefined names + * debugger - Command line input string conversion + * acpi_dump - ACPI table physical addresses + * acpi_exec - Support for namespace overrides * - * 2) The value must not exceed the maximum of an integer value. ACPI spec - * states the behavior is "unpredictable", so ACPICA matches the behavior - * of the implicit conversion case.(NO ERROR) + * Notes concerning users of these interfaces: * - * 3) Behavior on the first non-hex character is not specified by the ACPI - * spec, so ACPICA matches the behavior of the implicit conversion case - * and terminates. (NO ERROR) + * acpi_gbl_integer_byte_width is used to set the 32/64 bit limit for explicit + * and implicit conversions. This global must be set to the proper width. + * For the core ACPICA code, the width depends on the DSDT version. For the + * acpi_ut_strtoul64 interface, all conversions are 64 bits. This interface is + * used primarily for iASL, where the default width is 64 bits for all parsers, + * but error checking is performed later to flag cases where a 64-bit constant + * is wrongly defined in a 32-bit DSDT/SSDT. * - * 4) A null (zero-length) string is illegal. - * However, ACPICA allows this for compatibility with previous ACPICA. - * This conversion returns the value 0. (NO ERROR) + * In ACPI, the only place where octal numbers are supported is within + * the ASL language itself. This is implemented via the main acpi_ut_strtoul64 + * interface. According the ACPI specification, there is no ACPI runtime + * support (explicit/implicit) for octal string conversions. * ******************************************************************************/ - /******************************************************************************* * * FUNCTION: acpi_ut_strtoul64 * - * PARAMETERS: string - Null terminated input string - * flags - Conversion info, see below + * PARAMETERS: string - Null terminated input string, + * must be a valid pointer * return_value - Where the converted integer is - * returned - * - * RETURN: Status and Converted value + * returned. Must be a valid pointer * - * DESCRIPTION: Convert a string into an unsigned value. Performs either a - * 32-bit or 64-bit conversion, depending on the input integer - * size in Flags (often the current mode of the interpreter). + * RETURN: Status and converted integer. Returns an exception on a + * 64-bit numeric overflow * - * Values for Flags: - * ACPI_STRTOUL_32BIT - Max integer value is 32 bits - * ACPI_STRTOUL_64BIT - Max integer value is 64 bits - * ACPI_STRTOUL_BASE16 - Input string is hexadecimal. Default - * is 10/16 based on string prefix (0x). + * DESCRIPTION: Convert a string into an unsigned integer. Always performs a + * full 64-bit conversion, regardless of the current global + * integer width. Supports Decimal, Hex, and Octal strings. * - * NOTES: - * Negative numbers are not supported, as they are not supported by ACPI. + * Current users of this function: * - * Supports only base 16 or base 10 strings/values. Does not - * support Octal strings, as these are not supported by ACPI. - * - * Current users of this support: - * - * interpreter - Implicit and explicit conversions, GPE method names - * debugger - Command line input string conversion - * iASL - Main parser, conversion of constants to integers - * iASL - Data Table Compiler parser (constant math expressions) - * iASL - Preprocessor (constant math expressions) - * acpi_dump - Input table addresses - * acpi_exec - Testing of the acpi_ut_strtoul64 function - * - * Note concerning callers: - * acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used, - * this global should be set to the proper width. For the core ACPICA code, - * this width depends on the DSDT version. For iASL, the default byte - * width is always 8 for the parser, but error checking is performed later - * to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT. + * iASL - Preprocessor (constants and math expressions) + * iASL - Main ASL parser, conversion of ASL constants to integers + * iASL - Data Table Compiler parser (constants and math expressions) + * interpreter - Repair code for return values from predefined names + * acpi_dump - ACPI table physical addresses + * acpi_exec - Support for namespace overrides * ******************************************************************************/ - -acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value) +acpi_status acpi_ut_strtoul64(char *string, u64 *return_value) { acpi_status status = AE_OK; - u32 base; + u8 original_bit_width; + u32 base = 10; /* Default is decimal */ ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); - /* Parameter validation */ - - if (!string || !return_value) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - *return_value = 0; - /* Check for zero-length string, returns 0 */ + /* A NULL return string returns a value of zero */ if (*string == 0) { return_ACPI_STATUS(AE_OK); } - /* Skip over any white space at start of string */ - - while (isspace((int)*string)) { - string++; - } - - /* End of string? return 0 */ - - if (*string == 0) { + if (!acpi_ut_remove_whitespace(&string)) { return_ACPI_STATUS(AE_OK); } /* - * 1) The "0x" prefix indicates base 16. Per the ACPI specification, - * the "0x" prefix is only allowed for implicit (non-strict) conversions. - * However, we always allow it for compatibility with older ACPICA. + * 1) Check for a hex constant. A "0x" prefix indicates base 16. */ - if ((*string == ACPI_ASCII_ZERO) && - (tolower((int)*(string + 1)) == 'x')) { - string += 2; /* Go past the 0x */ - if (*string == 0) { - return_ACPI_STATUS(AE_OK); /* Return value 0 */ - } - + if (acpi_ut_detect_hex_prefix(&string)) { base = 16; } - /* 2) Force to base 16 (implicit conversion case) */ - - else if (flags & ACPI_STRTOUL_BASE16) { - base = 16; + /* + * 2) Check for an octal constant, defined to be a leading zero + * followed by sequence of octal digits (0-7) + */ + else if (acpi_ut_detect_octal_prefix(&string)) { + base = 8; } - /* 3) Default fallback is to Base 10 */ - - else { - base = 10; + if (!acpi_ut_remove_leading_zeros(&string)) { + return_ACPI_STATUS(AE_OK); /* Return value 0 */ } - /* Skip all leading zeros */ + /* + * Force a full 64-bit conversion. The caller (usually iASL) must + * check for a 32-bit overflow later as necessary (If current mode + * is 32-bit, meaning a 32-bit DSDT). + */ + original_bit_width = acpi_gbl_integer_bit_width; + acpi_gbl_integer_bit_width = 64; - while (*string == ACPI_ASCII_ZERO) { - string++; - if (*string == 0) { - return_ACPI_STATUS(AE_OK); /* Return value 0 */ - } + /* + * Perform the base 8, 10, or 16 conversion. A 64-bit numeric overflow + * will return an exception (to allow iASL to flag the statement). + */ + switch (base) { + case 8: + status = acpi_ut_convert_octal_string(string, return_value); + break; + + case 10: + status = acpi_ut_convert_decimal_string(string, return_value); + break; + + case 16: + default: + status = acpi_ut_convert_hex_string(string, return_value); + break; } - /* Perform the base 16 or 10 conversion */ - - if (base == 16) { - *return_value = acpi_ut_strtoul_base16(string, flags); - } else { - *return_value = acpi_ut_strtoul_base10(string, flags); - } + /* Only possible exception from above is a 64-bit overflow */ + acpi_gbl_integer_bit_width = original_bit_width; return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_ut_strtoul_base10 + * FUNCTION: acpi_ut_implicit_strtoul64 + * + * PARAMETERS: string - Null terminated input string, + * must be a valid pointer + * + * RETURN: Converted integer + * + * DESCRIPTION: Perform a 64-bit conversion with restrictions placed upon + * an "implicit conversion" by the ACPI specification. Used by + * many ASL operators that require an integer operand, and support + * an automatic (implicit) conversion from a string operand + * to the final integer operand. The major restriction is that + * only hex strings are supported. + * + * ----------------------------------------------------------------------------- + * + * Base is always 16, either with or without the 0x prefix. Decimal and + * Octal strings are not supported, as per the ACPI specification. + * + * Examples (both are hex values): + * Add ("BA98", Arg0, Local0) + * Subtract ("0x12345678", Arg1, Local1) + * + * Conversion rules as extracted from the ACPI specification: + * + * The converted integer is initialized to the value zero. + * The ASCII string is always interpreted as a hexadecimal constant. + * + * 1) According to the ACPI specification, a "0x" prefix is not allowed. + * However, ACPICA allows this as an ACPI extension on general + * principle. (NO ERROR) + * + * 2) The conversion terminates when the size of an integer is reached + * (32 or 64 bits). There are no numeric overflow conditions. (NO ERROR) + * + * 3) The first non-hex character terminates the conversion and returns + * the current accumulated value of the converted integer (NO ERROR). * - * PARAMETERS: string - Null terminated input string - * flags - Conversion info + * 4) Conversion of a null (zero-length) string to an integer is + * technically not allowed. However, ACPICA allows this as an ACPI + * extension. The conversion returns the value 0. (NO ERROR) * - * RETURN: 64-bit converted integer + * NOTE: There are no error conditions returned by this function. At + * the minimum, a value of zero is returned. * - * DESCRIPTION: Performs a base 10 conversion of the input string to an - * integer value, either 32 or 64 bits. - * Note: String must be valid and non-null. + * Current users of this function: + * + * interpreter - All runtime implicit conversions, as per ACPI specification + * iASL - Data Table Compiler parser (constants and math expressions) * ******************************************************************************/ -static u64 acpi_ut_strtoul_base10(char *string, u32 flags) +u64 acpi_ut_implicit_strtoul64(char *string) { - int ascii_digit; - u64 next_value; - u64 return_value = 0; - - /* Main loop: convert each ASCII byte in the input string */ - - while (*string) { - ascii_digit = *string; - if (!isdigit(ascii_digit)) { - - /* Not ASCII 0-9, terminate */ - - goto exit; - } - - /* Convert and insert (add) the decimal digit */ + u64 converted_integer = 0; - acpi_ut_short_multiply(return_value, 10, &next_value); - next_value += (ascii_digit - ACPI_ASCII_ZERO); + ACPI_FUNCTION_TRACE_STR(ut_implicit_strtoul64, string); - /* Check for overflow (32 or 64 bit) - return current converted value */ + if (!acpi_ut_remove_whitespace(&string)) { + return_VALUE(0); + } - if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) { /* 64-bit overflow case */ - goto exit; - } + /* + * Per the ACPI specification, only hexadecimal is supported for + * implicit conversions, and the "0x" prefix is "not allowed". + * However, allow a "0x" prefix as an ACPI extension. + */ + acpi_ut_detect_hex_prefix(&string); - return_value = next_value; - string++; + if (!acpi_ut_remove_leading_zeros(&string)) { + return_VALUE(0); } -exit: - return (return_value); + /* + * Ignore overflow as per the ACPI specification. This is implemented by + * ignoring the return status from the conversion function called below. + * On overflow, the input string is simply truncated. + */ + acpi_ut_convert_hex_string(string, &converted_integer); + return_VALUE(converted_integer); } /******************************************************************************* * - * FUNCTION: acpi_ut_strtoul_base16 + * FUNCTION: acpi_ut_explicit_strtoul64 + * + * PARAMETERS: string - Null terminated input string, + * must be a valid pointer * - * PARAMETERS: string - Null terminated input string - * flags - conversion info + * RETURN: Converted integer * - * RETURN: 64-bit converted integer + * DESCRIPTION: Perform a 64-bit conversion with the restrictions placed upon + * an "explicit conversion" by the ACPI specification. The + * main restriction is that only hex and decimal are supported. * - * DESCRIPTION: Performs a base 16 conversion of the input string to an - * integer value, either 32 or 64 bits. - * Note: String must be valid and non-null. + * ----------------------------------------------------------------------------- + * + * Base is either 10 (default) or 16 (with 0x prefix). Octal (base 8) strings + * are not supported, as per the ACPI specification. + * + * Examples: + * to_integer ("1000") Decimal + * to_integer ("0xABCD") Hex + * + * Conversion rules as extracted from the ACPI specification: + * + * 1) The input string is either a decimal or hexadecimal numeric string. + * A hex value must be prefixed by "0x" or it is interpreted as decimal. + * + * 2) The value must not exceed the maximum of an integer value + * (32 or 64 bits). The ACPI specification states the behavior is + * "unpredictable", so ACPICA matches the behavior of the implicit + * conversion case. There are no numeric overflow conditions. (NO ERROR) + * + * 3) Behavior on the first non-hex character is not defined by the ACPI + * specification (for the to_integer operator), so ACPICA matches the + * behavior of the implicit conversion case. It terminates the + * conversion and returns the current accumulated value of the converted + * integer. (NO ERROR) + * + * 4) Conversion of a null (zero-length) string to an integer is + * technically not allowed. However, ACPICA allows this as an ACPI + * extension. The conversion returns the value 0. (NO ERROR) + * + * NOTE: There are no error conditions returned by this function. At the + * minimum, a value of zero is returned. + * + * Current users of this function: + * + * interpreter - Runtime ASL to_integer operator, as per the ACPI specification * ******************************************************************************/ -static u64 acpi_ut_strtoul_base16(char *string, u32 flags) +u64 acpi_ut_explicit_strtoul64(char *string) { - int ascii_digit; - u32 valid_digits = 1; - u64 return_value = 0; - - /* Main loop: convert each ASCII byte in the input string */ + u64 converted_integer = 0; + u32 base = 10; /* Default is decimal */ - while (*string) { + ACPI_FUNCTION_TRACE_STR(ut_explicit_strtoul64, string); - /* Check for overflow (32 or 64 bit) - return current converted value */ - - if ((valid_digits > 16) || - ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) { - goto exit; - } - - ascii_digit = *string; - if (!isxdigit(ascii_digit)) { - - /* Not Hex ASCII A-F, a-f, or 0-9, terminate */ - - goto exit; - } + if (!acpi_ut_remove_whitespace(&string)) { + return_VALUE(0); + } - /* Convert and insert the hex digit */ + /* + * Only Hex and Decimal are supported, as per the ACPI specification. + * A "0x" prefix indicates hex; otherwise decimal is assumed. + */ + if (acpi_ut_detect_hex_prefix(&string)) { + base = 16; + } - acpi_ut_short_shift_left(return_value, 4, &return_value); - return_value |= acpi_ut_ascii_char_to_hex(ascii_digit); + if (!acpi_ut_remove_leading_zeros(&string)) { + return_VALUE(0); + } - string++; - valid_digits++; + /* + * Ignore overflow as per the ACPI specification. This is implemented by + * ignoring the return status from the conversion functions called below. + * On overflow, the input string is simply truncated. + */ + switch (base) { + case 10: + default: + acpi_ut_convert_decimal_string(string, &converted_integer); + break; + + case 16: + acpi_ut_convert_hex_string(string, &converted_integer); + break; } -exit: - return (return_value); + return_VALUE(converted_integer); } diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 3c8de88ecbd5..8cc70ca4e0fb 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -402,8 +402,8 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, allocation->component = component; allocation->line = line; - strncpy(allocation->module, module, ACPI_MAX_MODULE_NAME); - allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; + acpi_ut_safe_strncpy(allocation->module, (char *)module, + ACPI_MAX_MODULE_NAME); if (!element) { @@ -717,7 +717,7 @@ exit: if (!num_outstanding) { ACPI_INFO(("No outstanding allocations")); } else { - ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations", + ACPI_ERROR((AE_INFO, "%u (0x%X) Outstanding cache allocations", num_outstanding, num_outstanding)); } diff --git a/drivers/acpi/acpica/utuuid.c b/drivers/acpi/acpica/utuuid.c index 5028e06718b1..95946fdb55d5 100644 --- a/drivers/acpi/acpica/utuuid.c +++ b/drivers/acpi/acpica/utuuid.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 6b9ba4029f8e..25ef2ce64603 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index 950a1e500bfa..a78861ded894 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -96,8 +96,8 @@ ACPI_EXPORT_SYMBOL(acpi_error) * * RETURN: None * - * DESCRIPTION: Print "ACPI Exception" message with module/line/version info - * and decoded acpi_status. + * DESCRIPTION: Print an "ACPI Error" message with module/line/version + * info as well as decoded acpi_status. * ******************************************************************************/ void ACPI_INTERNAL_VAR_XFACE @@ -111,10 +111,10 @@ acpi_exception(const char *module_name, /* For AE_OK, just print the message */ if (ACPI_SUCCESS(status)) { - acpi_os_printf(ACPI_MSG_EXCEPTION); + acpi_os_printf(ACPI_MSG_ERROR); } else { - acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ", + acpi_os_printf(ACPI_MSG_ERROR "%s, ", acpi_format_exception(status)); } diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 6d5180601cf2..e727db52a55e 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxfmutex.c b/drivers/acpi/acpica/utxfmutex.c index 0b85f113f726..764782fcf1bd 100644 --- a/drivers/acpi/acpica/utxfmutex.c +++ b/drivers/acpi/acpica/utxfmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2017, Intel Corp. + * Copyright (C) 2000 - 2018, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 2c462beee551..9bff853e85f3 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -1007,7 +1007,7 @@ skip: /* The record may be cleared by others, try read next record */ if (len == -ENOENT) goto skip; - else if (len < sizeof(*rcd)) { + else if (len < 0 || len < sizeof(*rcd)) { rc = -EIO; goto out; } @@ -1061,7 +1061,7 @@ static int erst_writer(struct pstore_record *record) rcd->hdr.error_severity = CPER_SEV_FATAL; /* timestamp valid. platform_id, partition_id are invalid */ rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; - rcd->hdr.timestamp = get_seconds(); + rcd->hdr.timestamp = ktime_get_real_seconds(); rcd->hdr.record_length = sizeof(*rcd) + record->size; rcd->hdr.creator_id = CPER_CREATOR_PSTORE; rcd->hdr.notification_type = CPER_NOTIFY_MCE; diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 3c3a37b8503b..1efefe919555 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -51,6 +51,7 @@ #include <acpi/actbl1.h> #include <acpi/ghes.h> #include <acpi/apei.h> +#include <asm/fixmap.h> #include <asm/tlbflush.h> #include <ras/ras_event.h> @@ -112,22 +113,10 @@ static DEFINE_MUTEX(ghes_list_mutex); * Because the memory area used to transfer hardware error information * from BIOS to Linux can be determined only in NMI, IRQ or timer * handler, but general ioremap can not be used in atomic context, so - * a special version of atomic ioremap is implemented for that. - */ - -/* - * Two virtual pages are used, one for IRQ/PROCESS context, the other for - * NMI context (optionally). - */ -#define GHES_IOREMAP_PAGES 2 -#define GHES_IOREMAP_IRQ_PAGE(base) (base) -#define GHES_IOREMAP_NMI_PAGE(base) ((base) + PAGE_SIZE) - -/* virtual memory area for atomic ioremap */ -static struct vm_struct *ghes_ioremap_area; -/* - * These 2 spinlock is used to prevent atomic ioremap virtual memory - * area from being mapped simultaneously. + * the fixmap is used instead. + * + * These 2 spinlocks are used to prevent the fixmap entries from being used + * simultaneously. */ static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); @@ -140,71 +129,38 @@ static atomic_t ghes_estatus_cache_alloced; static int ghes_panic_timeout __read_mostly = 30; -static int ghes_ioremap_init(void) -{ - ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, - VM_IOREMAP, VMALLOC_START, VMALLOC_END); - if (!ghes_ioremap_area) { - pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n"); - return -ENOMEM; - } - - return 0; -} - -static void ghes_ioremap_exit(void) -{ - free_vm_area(ghes_ioremap_area); -} - static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) { - unsigned long vaddr; phys_addr_t paddr; pgprot_t prot; - vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr); - paddr = pfn << PAGE_SHIFT; prot = arch_apei_get_mem_attribute(paddr); - ioremap_page_range(vaddr, vaddr + PAGE_SIZE, paddr, prot); + __set_fixmap(FIX_APEI_GHES_NMI, paddr, prot); - return (void __iomem *)vaddr; + return (void __iomem *) fix_to_virt(FIX_APEI_GHES_NMI); } static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) { - unsigned long vaddr, paddr; + phys_addr_t paddr; pgprot_t prot; - vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr); - paddr = pfn << PAGE_SHIFT; prot = arch_apei_get_mem_attribute(paddr); + __set_fixmap(FIX_APEI_GHES_IRQ, paddr, prot); - ioremap_page_range(vaddr, vaddr + PAGE_SIZE, paddr, prot); - - return (void __iomem *)vaddr; + return (void __iomem *) fix_to_virt(FIX_APEI_GHES_IRQ); } -static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) +static void ghes_iounmap_nmi(void) { - unsigned long vaddr = (unsigned long __force)vaddr_ptr; - void *base = ghes_ioremap_area->addr; - - BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); - unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - arch_apei_flush_tlb_one(vaddr); + clear_fixmap(FIX_APEI_GHES_NMI); } -static void ghes_iounmap_irq(void __iomem *vaddr_ptr) +static void ghes_iounmap_irq(void) { - unsigned long vaddr = (unsigned long __force)vaddr_ptr; - void *base = ghes_ioremap_area->addr; - - BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); - unmap_kernel_range_noflush(vaddr, PAGE_SIZE); - arch_apei_flush_tlb_one(vaddr); + clear_fixmap(FIX_APEI_GHES_IRQ); } static int ghes_estatus_pool_init(void) @@ -360,10 +316,10 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, paddr += trunk; buffer += trunk; if (in_nmi) { - ghes_iounmap_nmi(vaddr); + ghes_iounmap_nmi(); raw_spin_unlock(&ghes_ioremap_lock_nmi); } else { - ghes_iounmap_irq(vaddr); + ghes_iounmap_irq(); spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); } } @@ -454,7 +410,52 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int flags = 0; if (flags != -1) - memory_failure_queue(pfn, 0, flags); + memory_failure_queue(pfn, flags); +#endif +} + +/* + * PCIe AER errors need to be sent to the AER driver for reporting and + * recovery. The GHES severities map to the following AER severities and + * require the following handling: + * + * GHES_SEV_CORRECTABLE -> AER_CORRECTABLE + * These need to be reported by the AER driver but no recovery is + * necessary. + * GHES_SEV_RECOVERABLE -> AER_NONFATAL + * GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL + * These both need to be reported and recovered from by the AER driver. + * GHES_SEV_PANIC does not make it to this handling since the kernel must + * panic. + */ +static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) +{ +#ifdef CONFIG_ACPI_APEI_PCIEAER + struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); + + if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && + pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { + unsigned int devfn; + int aer_severity; + + devfn = PCI_DEVFN(pcie_err->device_id.device, + pcie_err->device_id.function); + aer_severity = cper_severity_to_aer(gdata->error_severity); + + /* + * If firmware reset the component to contain + * the error, we must reinitialize it before + * use, so treat it as a fatal AER error. + */ + if (gdata->flags & CPER_SEC_RESET) + aer_severity = AER_FATAL; + + aer_recover_queue(pcie_err->device_id.segment, + pcie_err->device_id.bus, + devfn, aer_severity, + (struct aer_capability_regs *) + pcie_err->aer_info); + } #endif } @@ -485,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes, arch_apei_report_mem_error(sev, mem_err); ghes_handle_memory_failure(gdata, sev); } -#ifdef CONFIG_ACPI_APEI_PCIEAER else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { - struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); - - if (sev == GHES_SEV_RECOVERABLE && - sec_sev == GHES_SEV_RECOVERABLE && - pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && - pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { - unsigned int devfn; - int aer_severity; - - devfn = PCI_DEVFN(pcie_err->device_id.device, - pcie_err->device_id.function); - aer_severity = cper_severity_to_aer(gdata->error_severity); - - /* - * If firmware reset the component to contain - * the error, we must reinitialize it before - * use, so treat it as a fatal AER error. - */ - if (gdata->flags & CPER_SEC_RESET) - aer_severity = AER_FATAL; - - aer_recover_queue(pcie_err->device_id.segment, - pcie_err->device_id.bus, - devfn, aer_severity, - (struct aer_capability_regs *) - pcie_err->aer_info); - } - + ghes_handle_aer(gdata); } -#endif else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); @@ -774,9 +746,9 @@ static void ghes_add_timer(struct ghes *ghes) add_timer(&ghes->timer); } -static void ghes_poll_func(unsigned long data) +static void ghes_poll_func(struct timer_list *t) { - struct ghes *ghes = (void *)data; + struct ghes *ghes = from_timer(ghes, t, timer); ghes_proc(ghes); if (!(ghes->flags & GHES_EXITING)) @@ -851,17 +823,8 @@ static void ghes_sea_remove(struct ghes *ghes) synchronize_rcu(); } #else /* CONFIG_ACPI_APEI_SEA */ -static inline void ghes_sea_add(struct ghes *ghes) -{ - pr_err(GHES_PFX "ID: %d, trying to add SEA notification which is not supported\n", - ghes->generic->header.source_id); -} - -static inline void ghes_sea_remove(struct ghes *ghes) -{ - pr_err(GHES_PFX "ID: %d, trying to remove SEA notification which is not supported\n", - ghes->generic->header.source_id); -} +static inline void ghes_sea_add(struct ghes *ghes) { } +static inline void ghes_sea_remove(struct ghes *ghes) { } #endif /* CONFIG_ACPI_APEI_SEA */ #ifdef CONFIG_HAVE_ACPI_APEI_NMI @@ -923,7 +886,6 @@ static void ghes_print_queued_estatus(void) struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; struct acpi_hest_generic_status *estatus; - u32 len, node_len; llnode = llist_del_all(&ghes_estatus_llist); /* @@ -935,8 +897,6 @@ static void ghes_print_queued_estatus(void) estatus_node = llist_entry(llnode, struct ghes_estatus_node, llnode); estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - len = cper_estatus_len(estatus); - node_len = GHES_ESTATUS_NODE_LEN(len); generic = estatus_node->generic; ghes_print_estatus(NULL, generic, estatus); llnode = llnode->next; @@ -1063,23 +1023,9 @@ static void ghes_nmi_init_cxt(void) init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); } #else /* CONFIG_HAVE_ACPI_APEI_NMI */ -static inline void ghes_nmi_add(struct ghes *ghes) -{ - pr_err(GHES_PFX "ID: %d, trying to add NMI notification which is not supported!\n", - ghes->generic->header.source_id); - BUG(); -} - -static inline void ghes_nmi_remove(struct ghes *ghes) -{ - pr_err(GHES_PFX "ID: %d, trying to remove NMI notification which is not supported!\n", - ghes->generic->header.source_id); - BUG(); -} - -static inline void ghes_nmi_init_cxt(void) -{ -} +static inline void ghes_nmi_add(struct ghes *ghes) { } +static inline void ghes_nmi_remove(struct ghes *ghes) { } +static inline void ghes_nmi_init_cxt(void) { } #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ static int ghes_probe(struct platform_device *ghes_dev) @@ -1147,8 +1093,7 @@ static int ghes_probe(struct platform_device *ghes_dev) switch (generic->notify.type) { case ACPI_HEST_NOTIFY_POLLED: - setup_deferrable_timer(&ghes->timer, ghes_poll_func, - (unsigned long)ghes); + timer_setup(&ghes->timer, ghes_poll_func, TIMER_DEFERRABLE); ghes_add_timer(ghes); break; case ACPI_HEST_NOTIFY_EXTERNAL: @@ -1285,13 +1230,9 @@ static int __init ghes_init(void) ghes_nmi_init_cxt(); - rc = ghes_ioremap_init(); - if (rc) - goto err; - rc = ghes_estatus_pool_init(); if (rc) - goto err_ioremap_exit; + goto err; rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX); @@ -1315,8 +1256,6 @@ static int __init ghes_init(void) return 0; err_pool_exit: ghes_estatus_pool_exit(); -err_ioremap_exit: - ghes_ioremap_exit(); err: return rc; } diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index 597a737d538f..92f9edf9d11e 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -199,7 +199,7 @@ static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block, struct acpi_gtdt_timer_entry *gtdt_frame; if (!block->timer_count) { - pr_err(FW_BUG "GT block present, but frame count is zero."); + pr_err(FW_BUG "GT block present, but frame count is zero.\n"); return -ENODEV; } diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index de56394dd161..95255ecfae7c 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -88,8 +88,8 @@ static inline int iort_set_fwnode(struct acpi_iort_node *iort_node, * * Returns: fwnode_handle pointer on success, NULL on failure */ -static inline -struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node) +static inline struct fwnode_handle *iort_get_fwnode( + struct acpi_iort_node *node) { struct iort_fwnode *curr; struct fwnode_handle *fwnode = NULL; @@ -126,6 +126,31 @@ static inline void iort_delete_fwnode(struct acpi_iort_node *node) spin_unlock(&iort_fwnode_lock); } +/** + * iort_get_iort_node() - Retrieve iort_node associated with an fwnode + * + * @fwnode: fwnode associated with device to be looked-up + * + * Returns: iort_node pointer on success, NULL on failure + */ +static inline struct acpi_iort_node *iort_get_iort_node( + struct fwnode_handle *fwnode) +{ + struct iort_fwnode *curr; + struct acpi_iort_node *iort_node = NULL; + + spin_lock(&iort_fwnode_lock); + list_for_each_entry(curr, &iort_fwnode_list, list) { + if (curr->fwnode == fwnode) { + iort_node = curr->iort_node; + break; + } + } + spin_unlock(&iort_fwnode_lock); + + return iort_node; +} + typedef acpi_status (*iort_find_node_callback) (struct acpi_iort_node *node, void *context); @@ -306,9 +331,8 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, return 0; } -static -struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, - u32 *id_out, int index) +static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, + u32 *id_out, int index) { struct acpi_iort_node *parent; struct acpi_iort_id_mapping *map; @@ -332,7 +356,8 @@ 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_PCI_ROOT_COMPLEX || + node->type == ACPI_IORT_NODE_SMMU_V3) { *id_out = map->output_base; return parent; } @@ -341,6 +366,47 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, return NULL; } +#if (ACPI_CA_VERSION > 0x20170929) +static int iort_get_id_mapping_index(struct acpi_iort_node *node) +{ + struct acpi_iort_smmu_v3 *smmu; + + switch (node->type) { + case ACPI_IORT_NODE_SMMU_V3: + /* + * SMMUv3 dev ID mapping index was introduced in revision 1 + * table, not available in revision 0 + */ + if (node->revision < 1) + return -EINVAL; + + smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* + * ID mapping index is only ignored if all interrupts are + * GSIV based + */ + if (smmu->event_gsiv && smmu->pri_gsiv && smmu->gerr_gsiv + && smmu->sync_gsiv) + return -EINVAL; + + if (smmu->id_mapping_index >= node->mapping_count) { + pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n", + node, node->type); + return -EINVAL; + } + + return smmu->id_mapping_index; + default: + return -EINVAL; + } +} +#else +static inline int iort_get_id_mapping_index(struct acpi_iort_node *node) +{ + return -EINVAL; +} +#endif + static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, u32 id_in, u32 *id_out, u8 type_mask) @@ -350,7 +416,7 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, /* Parse the ID mapping tree to find specified node type */ while (node) { struct acpi_iort_id_mapping *map; - int i; + int i, index; if (IORT_TYPE_MASK(node->type) & type_mask) { if (id_out) @@ -371,8 +437,19 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, goto fail_map; } + /* + * Get the special ID mapping index (if any) and skip its + * associated ID map to prevent erroneous multi-stage + * IORT ID translations. + */ + index = iort_get_id_mapping_index(node); + /* Do the ID translation */ for (i = 0; i < node->mapping_count; i++, map++) { + /* if it is special mapping index, skip it */ + if (i == index) + continue; + if (!iort_id_map(map, node->type, id, &id)) break; } @@ -392,10 +469,9 @@ fail_map: return NULL; } -static -struct acpi_iort_node *iort_node_map_platform_id(struct acpi_iort_node *node, - u32 *id_out, u8 type_mask, - int index) +static struct acpi_iort_node *iort_node_map_platform_id( + struct acpi_iort_node *node, u32 *id_out, u8 type_mask, + int index) { struct acpi_iort_node *parent; u32 id; @@ -424,9 +500,25 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev) { struct pci_bus *pbus; - if (!dev_is_pci(dev)) + if (!dev_is_pci(dev)) { + struct acpi_iort_node *node; + /* + * scan iort_fwnode_list to see if it's an iort platform + * device (such as SMMU, PMCG),its iort node already cached + * and associated with fwnode when iort platform devices + * were initialized. + */ + node = iort_get_iort_node(dev->fwnode); + if (node) + return node; + + /* + * if not, then it should be a platform device defined in + * DSDT/SSDT (with Named Component node in IORT) + */ return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, iort_match_node_callback, dev); + } /* Find a PCI root bus */ pbus = to_pci_dev(dev)->bus; @@ -466,16 +558,24 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id) */ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) { - int i; + int i, index; struct acpi_iort_node *node; node = iort_find_dev_node(dev); if (!node) return -ENODEV; - for (i = 0; i < node->mapping_count; i++) { - if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i)) + index = iort_get_id_mapping_index(node); + /* if there is a valid index, go get the dev_id directly */ + if (index >= 0) { + if (iort_node_get_id(node, dev_id, index)) return 0; + } else { + for (i = 0; i < node->mapping_count; i++) { + if (iort_node_map_platform_id(node, dev_id, + IORT_MSI_TYPE, i)) + return 0; + } } return -ENODEV; @@ -538,6 +638,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); } +static void iort_set_device_domain(struct device *dev, + struct acpi_iort_node *node) +{ + struct acpi_iort_its_group *its; + struct acpi_iort_node *msi_parent; + struct acpi_iort_id_mapping *map; + struct fwnode_handle *iort_fwnode; + struct irq_domain *domain; + int index; + + index = iort_get_id_mapping_index(node); + if (index < 0) + return; + + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, + node->mapping_offset + index * sizeof(*map)); + + /* Firmware bug! */ + if (!map->output_reference || + !(map->flags & ACPI_IORT_ID_SINGLE_MAPPING)) { + pr_err(FW_BUG "[node %p type %d] Invalid MSI mapping\n", + node, node->type); + return; + } + + msi_parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, + map->output_reference); + + if (!msi_parent || msi_parent->type != ACPI_IORT_NODE_ITS_GROUP) + return; + + /* Move to ITS specific data */ + its = (struct acpi_iort_its_group *)msi_parent->node_data; + + iort_fwnode = iort_find_domain_token(its->identifiers[0]); + if (!iort_fwnode) + return; + + domain = irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI); + if (domain) + dev_set_msi_domain(dev, domain); +} + /** * iort_get_platform_device_domain() - Find MSI domain related to a * platform device @@ -623,14 +766,14 @@ static inline bool iort_iommu_driver_enabled(u8 type) } #ifdef CONFIG_IOMMU_API -static inline -const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec) +static inline const struct iommu_ops *iort_fwspec_iommu_ops( + struct iommu_fwspec *fwspec) { return (fwspec && fwspec->ops) ? fwspec->ops : NULL; } -static inline -int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) +static inline int iort_add_device_replay(const struct iommu_ops *ops, + struct device *dev) { int err = 0; @@ -640,11 +783,11 @@ int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) return err; } #else -static inline -const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec) +static inline const struct iommu_ops *iort_fwspec_iommu_ops( + struct iommu_fwspec *fwspec) { return NULL; } -static inline -int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) +static inline int iort_add_device_replay(const struct iommu_ops *ops, + struct device *dev) { return 0; } #endif @@ -968,7 +1111,7 @@ static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node) return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE; } -#if defined(CONFIG_ACPI_NUMA) && defined(ACPI_IORT_SMMU_V3_PXM_VALID) +#if defined(CONFIG_ACPI_NUMA) /* * set numa proximity domain for smmuv3 device */ @@ -1051,34 +1194,34 @@ static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node) return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK; } -struct iort_iommu_config { +struct iort_dev_config { const char *name; - int (*iommu_init)(struct acpi_iort_node *node); - bool (*iommu_is_coherent)(struct acpi_iort_node *node); - int (*iommu_count_resources)(struct acpi_iort_node *node); - void (*iommu_init_resources)(struct resource *res, + int (*dev_init)(struct acpi_iort_node *node); + bool (*dev_is_coherent)(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 (*iommu_set_proximity)(struct device *dev, + void (*dev_set_proximity)(struct device *dev, struct acpi_iort_node *node); }; -static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = { +static const struct iort_dev_config iort_arm_smmu_v3_cfg __initconst = { .name = "arm-smmu-v3", - .iommu_is_coherent = arm_smmu_v3_is_coherent, - .iommu_count_resources = arm_smmu_v3_count_resources, - .iommu_init_resources = arm_smmu_v3_init_resources, - .iommu_set_proximity = arm_smmu_v3_set_proximity, + .dev_is_coherent = arm_smmu_v3_is_coherent, + .dev_count_resources = arm_smmu_v3_count_resources, + .dev_init_resources = arm_smmu_v3_init_resources, + .dev_set_proximity = arm_smmu_v3_set_proximity, }; -static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = { +static const struct iort_dev_config iort_arm_smmu_cfg __initconst = { .name = "arm-smmu", - .iommu_is_coherent = arm_smmu_is_coherent, - .iommu_count_resources = arm_smmu_count_resources, - .iommu_init_resources = arm_smmu_init_resources + .dev_is_coherent = arm_smmu_is_coherent, + .dev_count_resources = arm_smmu_count_resources, + .dev_init_resources = arm_smmu_init_resources }; -static __init -const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node) +static __init const struct iort_dev_config *iort_get_dev_cfg( + struct acpi_iort_node *node) { switch (node->type) { case ACPI_IORT_NODE_SMMU_V3: @@ -1091,31 +1234,28 @@ const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node) } /** - * iort_add_smmu_platform_device() - Allocate a platform device for SMMU - * @node: Pointer to SMMU ACPI IORT node + * iort_add_platform_device() - Allocate a platform device for IORT node + * @node: Pointer to device ACPI IORT node * * Returns: 0 on success, <0 failure */ -static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) +static int __init iort_add_platform_device(struct acpi_iort_node *node, + const struct iort_dev_config *ops) { struct fwnode_handle *fwnode; struct platform_device *pdev; struct resource *r; enum dev_dma_attr attr; int ret, count; - const struct iort_iommu_config *ops = iort_get_iommu_cfg(node); - - if (!ops) - return -ENODEV; pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO); if (!pdev) return -ENOMEM; - if (ops->iommu_set_proximity) - ops->iommu_set_proximity(&pdev->dev, node); + if (ops->dev_set_proximity) + ops->dev_set_proximity(&pdev->dev, node); - count = ops->iommu_count_resources(node); + count = ops->dev_count_resources(node); r = kcalloc(count, sizeof(*r), GFP_KERNEL); if (!r) { @@ -1123,7 +1263,7 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) goto dev_put; } - ops->iommu_init_resources(r, node); + ops->dev_init_resources(r, node); ret = platform_device_add_resources(pdev, r, count); /* @@ -1158,12 +1298,14 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) pdev->dev.fwnode = fwnode; - attr = ops->iommu_is_coherent(node) ? - DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT; + 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); + iort_set_device_domain(&pdev->dev, node); + ret = platform_device_add(pdev); if (ret) goto dma_deconfigure; @@ -1216,6 +1358,7 @@ static void __init iort_init_platform_devices(void) struct fwnode_handle *fwnode; int i, ret; bool acs_enabled = false; + const struct iort_dev_config *ops; /* * iort_table and iort both point to the start of IORT table, but @@ -1238,16 +1381,15 @@ static void __init iort_init_platform_devices(void) if (!acs_enabled) acs_enabled = iort_enable_acs(iort_node); - if ((iort_node->type == ACPI_IORT_NODE_SMMU) || - (iort_node->type == ACPI_IORT_NODE_SMMU_V3)) { - + ops = iort_get_dev_cfg(iort_node); + if (ops) { fwnode = acpi_alloc_fwnode_static(); if (!fwnode) return; iort_set_fwnode(iort_node, fwnode); - ret = iort_add_smmu_platform_device(iort_node); + ret = iort_add_platform_device(iort_node, ops); if (ret) { iort_delete_fwnode(iort_node); acpi_free_fwnode_static(fwnode); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 13e7b56e33ae..7128488a3a72 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -70,6 +70,7 @@ static async_cookie_t async_cookie; static bool battery_driver_registered; static int battery_bix_broken_package; static int battery_notification_delay_ms; +static int battery_full_discharging; static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); @@ -214,9 +215,12 @@ static int acpi_battery_get_property(struct power_supply *psy, return -ENODEV; switch (psp) { case POWER_SUPPLY_PROP_STATUS: - if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; - else if (battery->state & ACPI_BATTERY_STATE_CHARGING) + if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) { + if (battery_full_discharging && battery->rate_now == 0) + val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + } else if (battery->state & ACPI_BATTERY_STATE_CHARGING) val->intval = POWER_SUPPLY_STATUS_CHARGING; else if (acpi_battery_is_charged(battery)) val->intval = POWER_SUPPLY_STATUS_FULL; @@ -1166,6 +1170,12 @@ battery_notification_delay_quirk(const struct dmi_system_id *d) return 0; } +static int __init battery_full_discharging_quirk(const struct dmi_system_id *d) +{ + battery_full_discharging = 1; + return 0; +} + static const struct dmi_system_id bat_dmi_table[] __initconst = { { .callback = battery_bix_broken_package_quirk, @@ -1183,6 +1193,38 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"), }, }, + { + .callback = battery_full_discharging_quirk, + .ident = "ASUS GL502VSK", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GL502VSK"), + }, + }, + { + .callback = battery_full_discharging_quirk, + .ident = "ASUS UX305LA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX305LA"), + }, + }, + { + .callback = battery_full_discharging_quirk, + .ident = "ASUS UX360UA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX360UA"), + }, + }, + { + .callback = battery_full_discharging_quirk, + .ident = "ASUS UX410UAK", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX410UAK"), + }, + }, {}, }; @@ -1237,13 +1279,11 @@ static int acpi_battery_add(struct acpi_device *device) #ifdef CONFIG_ACPI_PROCFS_POWER result = acpi_battery_add_fs(device); -#endif if (result) { -#ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); -#endif goto fail; } +#endif printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 4d0979e02a28..0dad0bd9327b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -66,10 +66,37 @@ static int set_copy_dsdt(const struct dmi_system_id *id) return 0; } #endif +static int set_gbl_term_list(const struct dmi_system_id *id) +{ + acpi_gbl_parse_table_as_term_list = 1; + return 0; +} -static const struct dmi_system_id dsdt_dmi_table[] __initconst = { +static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = { + /* + * Touchpad on Dell XPS 9570/Precision M5530 doesn't work under I2C + * mode. + * https://bugzilla.kernel.org/show_bug.cgi?id=198515 + */ + { + .callback = set_gbl_term_list, + .ident = "Dell Precision M5530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision M5530"), + }, + }, + { + .callback = set_gbl_term_list, + .ident = "Dell XPS 15 9570", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9570"), + }, + }, /* * Invoke DSDT corruption work-around on all Toshiba Satellite. + * DSDT will be copied to memory. * https://bugzilla.kernel.org/show_bug.cgi?id=14679 */ { @@ -83,7 +110,7 @@ static const struct dmi_system_id dsdt_dmi_table[] __initconst = { {} }; #else -static const struct dmi_system_id dsdt_dmi_table[] __initconst = { +static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = { {} }; #endif @@ -108,6 +135,7 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle, } return status; } +EXPORT_SYMBOL_GPL(acpi_bus_get_status_handle); int acpi_bus_get_status(struct acpi_device *device) { @@ -119,6 +147,12 @@ int acpi_bus_get_status(struct acpi_device *device) return 0; } + /* Battery devices must have their deps met before calling _STA */ + if (acpi_device_is_battery(device) && device->dep_unmet) { + acpi_set_device_status(device, 0); + return 0; + } + status = acpi_bus_get_status_handle(device->handle, &sta); if (ACPI_FAILURE(status)) return -ENODEV; @@ -626,13 +660,15 @@ struct acpi_device *acpi_companion_match(const struct device *dev) * acpi_of_match_device - Match device object using the "compatible" property. * @adev: ACPI device object to match. * @of_match_table: List of device IDs to match against. + * @of_id: OF ID if matched * * If @dev has an ACPI companion which has ACPI_DT_NAMESPACE_HID in its list of * identifiers and a _DSD object with the "compatible" property, use that * property to match against the given list of identifiers. */ static bool acpi_of_match_device(struct acpi_device *adev, - const struct of_device_id *of_match_table) + const struct of_device_id *of_match_table, + const struct of_device_id **of_id) { const union acpi_object *of_compatible, *obj; int i, nval; @@ -656,8 +692,11 @@ static bool acpi_of_match_device(struct acpi_device *adev, const struct of_device_id *id; for (id = of_match_table; id->compatible[0]; id++) - if (!strcasecmp(obj->string.pointer, id->compatible)) + if (!strcasecmp(obj->string.pointer, id->compatible)) { + if (of_id) + *of_id = id; return true; + } } return false; @@ -728,10 +767,11 @@ static bool __acpi_match_device_cls(const struct acpi_device_id *id, return true; } -static const struct acpi_device_id *__acpi_match_device( - struct acpi_device *device, - const struct acpi_device_id *ids, - const struct of_device_id *of_ids) +static bool __acpi_match_device(struct acpi_device *device, + const struct acpi_device_id *acpi_ids, + const struct of_device_id *of_ids, + const struct acpi_device_id **acpi_id, + const struct of_device_id **of_id) { const struct acpi_device_id *id; struct acpi_hardware_id *hwid; @@ -741,30 +781,32 @@ static const struct acpi_device_id *__acpi_match_device( * driver for it. */ if (!device || !device->status.present) - return NULL; + return false; list_for_each_entry(hwid, &device->pnp.ids, list) { /* First, check the ACPI/PNP IDs provided by the caller. */ - for (id = ids; id->id[0] || id->cls; id++) { - if (id->id[0] && !strcmp((char *) id->id, hwid->id)) - return id; - else if (id->cls && __acpi_match_device_cls(id, hwid)) - return id; + if (acpi_ids) { + for (id = acpi_ids; id->id[0] || id->cls; id++) { + if (id->id[0] && !strcmp((char *)id->id, hwid->id)) + goto out_acpi_match; + if (id->cls && __acpi_match_device_cls(id, hwid)) + goto out_acpi_match; + } } /* * Next, check ACPI_DT_NAMESPACE_HID and try to match the * "compatible" property if found. - * - * The id returned by the below is not valid, but the only - * caller passing non-NULL of_ids here is only interested in - * whether or not the return value is NULL. */ - if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id) - && acpi_of_match_device(device, of_ids)) - return id; + if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)) + return acpi_of_match_device(device, of_ids, of_id); } - return NULL; + return false; + +out_acpi_match: + if (acpi_id) + *acpi_id = id; + return true; } /** @@ -781,14 +823,29 @@ static const struct acpi_device_id *__acpi_match_device( const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, const struct device *dev) { - return __acpi_match_device(acpi_companion_match(dev), ids, NULL); + const struct acpi_device_id *id = NULL; + + __acpi_match_device(acpi_companion_match(dev), ids, NULL, &id, NULL); + return id; } EXPORT_SYMBOL_GPL(acpi_match_device); +const void *acpi_device_get_match_data(const struct device *dev) +{ + const struct acpi_device_id *match; + + match = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!match) + return NULL; + + return (const void *)match->driver_data; +} +EXPORT_SYMBOL_GPL(acpi_device_get_match_data); + int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids) { - return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT; + return __acpi_match_device(device, ids, NULL, NULL, NULL) ? 0 : -ENOENT; } EXPORT_SYMBOL(acpi_match_device_ids); @@ -797,10 +854,12 @@ bool acpi_driver_match_device(struct device *dev, { if (!drv->acpi_match_table) return acpi_of_match_device(ACPI_COMPANION(dev), - drv->of_match_table); + drv->of_match_table, + NULL); - return !!__acpi_match_device(acpi_companion_match(dev), - drv->acpi_match_table, drv->of_match_table); + return __acpi_match_device(acpi_companion_match(dev), + drv->acpi_match_table, drv->of_match_table, + NULL, NULL); } EXPORT_SYMBOL_GPL(acpi_driver_match_device); @@ -1001,11 +1060,8 @@ void __init acpi_early_init(void) acpi_permanent_mmap = true; - /* - * If the machine falls into the DMI check table, - * DSDT will be copied to memory - */ - dmi_check_system(dsdt_dmi_table); + /* Check machine-specific quirks */ + dmi_check_system(acpi_quirks_dmi_table); status = acpi_reallocate_root_table(); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index ef1856b15488..e1eee7a60fad 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -30,6 +30,7 @@ #include <linux/input.h> #include <linux/slab.h> #include <linux/acpi.h> +#include <linux/dmi.h> #include <acpi/button.h> #define PREFIX "ACPI: " @@ -76,6 +77,22 @@ static const struct acpi_device_id button_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, button_device_ids); +/* + * Some devices which don't even have a lid in anyway have a broken _LID + * method (e.g. pointing to a floating gpio pin) causing spurious LID events. + */ +static const struct dmi_system_id lid_blacklst[] = { + { + /* GP-electronic T701 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "T701"), + DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"), + }, + }, + {} +}; + static int acpi_button_add(struct acpi_device *device); static int acpi_button_remove(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); @@ -210,6 +227,8 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) } /* Send the platform triggered reliable event */ if (do_update) { + acpi_handle_debug(device->handle, "ACPI LID %s\n", + state ? "open" : "closed"); input_report_switch(button->input, SW_LID, !state); input_sync(button->input); button->last_state = !!state; @@ -390,6 +409,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) { struct acpi_button *button = acpi_driver_data(device); struct input_dev *input; + int users; switch (event) { case ACPI_FIXED_HARDWARE_EVENT: @@ -398,7 +418,11 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) case ACPI_BUTTON_NOTIFY_STATUS: input = button->input; if (button->type == ACPI_BUTTON_TYPE_LID) { - acpi_lid_update_state(device); + mutex_lock(&button->input->mutex); + users = button->input->users; + mutex_unlock(&button->input->mutex); + if (users) + acpi_lid_update_state(device); } else { int keycode; @@ -442,12 +466,24 @@ 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) + if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) acpi_lid_initialize_state(device); return 0; } #endif +static int acpi_lid_input_open(struct input_dev *input) +{ + struct acpi_device *device = input_get_drvdata(input); + struct acpi_button *button = acpi_driver_data(device); + + button->last_state = !!acpi_lid_evaluate_state(device); + button->last_time = ktime_get(); + acpi_lid_initialize_state(device); + + return 0; +} + static int acpi_button_add(struct acpi_device *device) { struct acpi_button *button; @@ -456,6 +492,9 @@ static int acpi_button_add(struct acpi_device *device) char *name, *class; int error; + if (!strcmp(hid, ACPI_BUTTON_HID_LID) && dmi_check_system(lid_blacklst)) + return -ENODEV; + button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); if (!button) return -ENOMEM; @@ -488,8 +527,7 @@ static int acpi_button_add(struct acpi_device *device) strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); sprintf(class, "%s/%s", ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); - button->last_state = !!acpi_lid_evaluate_state(device); - button->last_time = ktime_get(); + input->open = acpi_lid_input_open; } else { printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); error = -ENODEV; @@ -522,11 +560,11 @@ static int acpi_button_add(struct acpi_device *device) break; } + input_set_drvdata(input, device); error = input_register_device(input); if (error) goto err_remove_fs; if (button->type == ACPI_BUTTON_TYPE_LID) { - acpi_lid_initialize_state(device); /* * This assumes there's only one lid device, or if there are * more we only care about the last one... @@ -557,7 +595,8 @@ static int acpi_button_remove(struct acpi_device *device) return 0; } -static int param_set_lid_init_state(const char *val, struct kernel_param *kp) +static int param_set_lid_init_state(const char *val, + const struct kernel_param *kp) { int result = 0; @@ -575,7 +614,8 @@ static int param_set_lid_init_state(const char *val, struct kernel_param *kp) return result; } -static int param_get_lid_init_state(char *buffer, struct kernel_param *kp) +static int param_get_lid_init_state(char *buffer, + const struct kernel_param *kp) { switch (lid_init_state) { case ACPI_BUTTON_LID_INIT_OPEN: diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index e5b47f032d9a..0afbb2658cbc 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -48,7 +48,6 @@ struct cppc_pcc_data { struct mbox_chan *pcc_channel; void __iomem *pcc_comm_addr; - int pcc_subspace_idx; bool pcc_channel_acquired; ktime_t deadline; unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; @@ -75,13 +74,16 @@ struct cppc_pcc_data { /* Wait queue for CPUs whose requests were batched */ wait_queue_head_t pcc_write_wait_q; + ktime_t last_cmd_cmpl_time; + ktime_t last_mpar_reset; + int mpar_count; + int refcount; }; -/* Structure to represent the single PCC channel */ -static struct cppc_pcc_data pcc_data = { - .pcc_subspace_idx = -1, - .platform_owns_pcc = true, -}; +/* 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 */ +static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx); /* * The cpc_desc structure contains the ACPI register details @@ -93,7 +95,8 @@ static struct cppc_pcc_data pcc_data = { static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); /* pcc mapped address + header size + offset within PCC subspace */ -#define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs)) +#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \ + 0x8 + (offs)) /* Check if a CPC register is in PCC */ #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ @@ -116,7 +119,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); * to PCC commands. Keeping it high enough to cover emulators where * the processors run painfully slow. */ -#define NUM_RETRIES 500 +#define NUM_RETRIES 500ULL struct cppc_attr { struct attribute attr; @@ -188,13 +191,16 @@ static struct kobj_type cppc_ktype = { .default_attrs = cppc_attrs, }; -static int check_pcc_chan(bool chk_err_bit) +static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) { int ret = -EIO, status = 0; - struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; - ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); + struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; + struct acpi_pcct_shared_memory __iomem *generic_comm_base = + pcc_ss_data->pcc_comm_addr; + ktime_t next_deadline = ktime_add(ktime_get(), + pcc_ss_data->deadline); - if (!pcc_data.platform_owns_pcc) + if (!pcc_ss_data->platform_owns_pcc) return 0; /* Retry in case the remote processor was too slow to catch up. */ @@ -219,7 +225,7 @@ static int check_pcc_chan(bool chk_err_bit) } if (likely(!ret)) - pcc_data.platform_owns_pcc = false; + pcc_ss_data->platform_owns_pcc = false; else pr_err("PCC check channel failed. Status=%x\n", status); @@ -230,13 +236,12 @@ static int check_pcc_chan(bool chk_err_bit) * This function transfers the ownership of the PCC to the platform * So it must be called while holding write_lock(pcc_lock) */ -static int send_pcc_cmd(u16 cmd) +static int send_pcc_cmd(int pcc_ss_id, u16 cmd) { int ret = -EIO, i; + struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; struct acpi_pcct_shared_memory *generic_comm_base = - (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr; - static ktime_t last_cmd_cmpl_time, last_mpar_reset; - static int mpar_count; + (struct acpi_pcct_shared_memory *)pcc_ss_data->pcc_comm_addr; unsigned int time_delta; /* @@ -249,24 +254,25 @@ static int send_pcc_cmd(u16 cmd) * before write completion, so first send a WRITE command to * platform */ - if (pcc_data.pending_pcc_write_cmd) - send_pcc_cmd(CMD_WRITE); + if (pcc_ss_data->pending_pcc_write_cmd) + send_pcc_cmd(pcc_ss_id, CMD_WRITE); - ret = check_pcc_chan(false); + ret = check_pcc_chan(pcc_ss_id, false); if (ret) goto end; } else /* CMD_WRITE */ - pcc_data.pending_pcc_write_cmd = FALSE; + pcc_ss_data->pending_pcc_write_cmd = FALSE; /* * Handle the Minimum Request Turnaround Time(MRTT) * "The minimum amount of time that OSPM must wait after the completion * of a command before issuing the next command, in microseconds" */ - if (pcc_data.pcc_mrtt) { - time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); - if (pcc_data.pcc_mrtt > time_delta) - udelay(pcc_data.pcc_mrtt - time_delta); + if (pcc_ss_data->pcc_mrtt) { + time_delta = ktime_us_delta(ktime_get(), + pcc_ss_data->last_cmd_cmpl_time); + if (pcc_ss_data->pcc_mrtt > time_delta) + udelay(pcc_ss_data->pcc_mrtt - time_delta); } /* @@ -280,18 +286,19 @@ static int send_pcc_cmd(u16 cmd) * not send the request to the platform after hitting the MPAR limit in * any 60s window */ - if (pcc_data.pcc_mpar) { - if (mpar_count == 0) { - time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); - if (time_delta < 60 * MSEC_PER_SEC) { + if (pcc_ss_data->pcc_mpar) { + if (pcc_ss_data->mpar_count == 0) { + time_delta = ktime_ms_delta(ktime_get(), + pcc_ss_data->last_mpar_reset); + if ((time_delta < 60 * MSEC_PER_SEC) && pcc_ss_data->last_mpar_reset) { pr_debug("PCC cmd not sent due to MPAR limit"); ret = -EIO; goto end; } - last_mpar_reset = ktime_get(); - mpar_count = pcc_data.pcc_mpar; + pcc_ss_data->last_mpar_reset = ktime_get(); + pcc_ss_data->mpar_count = pcc_ss_data->pcc_mpar; } - mpar_count--; + pcc_ss_data->mpar_count--; } /* Write to the shared comm region. */ @@ -300,10 +307,10 @@ static int send_pcc_cmd(u16 cmd) /* Flip CMD COMPLETE bit */ writew_relaxed(0, &generic_comm_base->status); - pcc_data.platform_owns_pcc = true; + pcc_ss_data->platform_owns_pcc = true; /* Ring doorbell */ - ret = mbox_send_message(pcc_data.pcc_channel, &cmd); + ret = mbox_send_message(pcc_ss_data->pcc_channel, &cmd); if (ret < 0) { pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", cmd, ret); @@ -311,15 +318,15 @@ static int send_pcc_cmd(u16 cmd) } /* wait for completion and check for PCC errro bit */ - ret = check_pcc_chan(true); + ret = check_pcc_chan(pcc_ss_id, true); - if (pcc_data.pcc_mrtt) - last_cmd_cmpl_time = ktime_get(); + if (pcc_ss_data->pcc_mrtt) + pcc_ss_data->last_cmd_cmpl_time = ktime_get(); - if (pcc_data.pcc_channel->mbox->txdone_irq) - mbox_chan_txdone(pcc_data.pcc_channel, ret); + if (pcc_ss_data->pcc_channel->mbox->txdone_irq) + mbox_chan_txdone(pcc_ss_data->pcc_channel, ret); else - mbox_client_txdone(pcc_data.pcc_channel, ret); + mbox_client_txdone(pcc_ss_data->pcc_channel, ret); end: if (cmd == CMD_WRITE) { @@ -329,12 +336,12 @@ end: if (!desc) continue; - if (desc->write_cmd_id == pcc_data.pcc_write_cnt) + if (desc->write_cmd_id == pcc_ss_data->pcc_write_cnt) desc->write_cmd_status = ret; } } - pcc_data.pcc_write_cnt++; - wake_up_all(&pcc_data.pcc_write_wait_q); + pcc_ss_data->pcc_write_cnt++; + wake_up_all(&pcc_ss_data->pcc_write_wait_q); } return ret; @@ -536,16 +543,16 @@ err_ret: } EXPORT_SYMBOL_GPL(acpi_get_psd_map); -static int register_pcc_channel(int pcc_subspace_idx) +static int register_pcc_channel(int pcc_ss_idx) { struct acpi_pcct_hw_reduced *cppc_ss; u64 usecs_lat; - if (pcc_subspace_idx >= 0) { - pcc_data.pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl, - pcc_subspace_idx); + if (pcc_ss_idx >= 0) { + pcc_data[pcc_ss_idx]->pcc_channel = + pcc_mbox_request_channel(&cppc_mbox_cl, pcc_ss_idx); - if (IS_ERR(pcc_data.pcc_channel)) { + if (IS_ERR(pcc_data[pcc_ss_idx]->pcc_channel)) { pr_err("Failed to find PCC communication channel\n"); return -ENODEV; } @@ -556,7 +563,7 @@ static int register_pcc_channel(int pcc_subspace_idx) * PCC channels) and stored pointers to the * subspace communication region in con_priv. */ - cppc_ss = (pcc_data.pcc_channel)->con_priv; + cppc_ss = (pcc_data[pcc_ss_idx]->pcc_channel)->con_priv; if (!cppc_ss) { pr_err("No PCC subspace found for CPPC\n"); @@ -569,19 +576,20 @@ static int register_pcc_channel(int pcc_subspace_idx) * So add an arbitrary amount of wait on top of Nominal. */ usecs_lat = NUM_RETRIES * cppc_ss->latency; - pcc_data.deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); - pcc_data.pcc_mrtt = cppc_ss->min_turnaround_time; - pcc_data.pcc_mpar = cppc_ss->max_access_rate; - pcc_data.pcc_nominal = cppc_ss->latency; - - pcc_data.pcc_comm_addr = acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); - if (!pcc_data.pcc_comm_addr) { + pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); + pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; + pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; + pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; + + pcc_data[pcc_ss_idx]->pcc_comm_addr = + acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); + if (!pcc_data[pcc_ss_idx]->pcc_comm_addr) { pr_err("Failed to ioremap PCC comm region mem\n"); return -ENOMEM; } /* Set flag so that we dont come here for each CPU. */ - pcc_data.pcc_channel_acquired = true; + pcc_data[pcc_ss_idx]->pcc_channel_acquired = true; } return 0; @@ -600,6 +608,34 @@ bool __weak cpc_ffh_supported(void) return false; } + +/** + * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace + * + * 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 + * with hardware multi-threading support. + * + * Return: 0 for success, errno for failure + */ +int pcc_data_alloc(int pcc_ss_id) +{ + if (pcc_ss_id < 0 || pcc_ss_id >= MAX_PCC_SUBSPACES) + return -EINVAL; + + if (pcc_data[pcc_ss_id]) { + pcc_data[pcc_ss_id]->refcount++; + } else { + pcc_data[pcc_ss_id] = kzalloc(sizeof(struct cppc_pcc_data), + GFP_KERNEL); + if (!pcc_data[pcc_ss_id]) + return -ENOMEM; + pcc_data[pcc_ss_id]->refcount++; + } + + return 0; +} /* * An example CPC table looks like the following. * @@ -661,6 +697,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) struct device *cpu_dev; acpi_handle handle = pr->handle; unsigned int num_ent, i, cpc_rev; + int pcc_subspace_id = -1; acpi_status status; int ret = -EFAULT; @@ -733,9 +770,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) * so extract it only once. */ if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { - if (pcc_data.pcc_subspace_idx < 0) - pcc_data.pcc_subspace_idx = gas_t->access_width; - else if (pcc_data.pcc_subspace_idx != gas_t->access_width) { + if (pcc_subspace_id < 0) { + pcc_subspace_id = gas_t->access_width; + if (pcc_data_alloc(pcc_subspace_id)) + goto out_free; + } else if (pcc_subspace_id != gas_t->access_width) { pr_debug("Mismatched PCC ids.\n"); goto out_free; } @@ -763,6 +802,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) goto out_free; } } + per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; /* Store CPU Logical ID */ cpc_ptr->cpu_id = pr->id; @@ -771,14 +811,14 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) if (ret) goto out_free; - /* Register PCC channel once for all CPUs. */ - if (!pcc_data.pcc_channel_acquired) { - ret = register_pcc_channel(pcc_data.pcc_subspace_idx); + /* 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) goto out_free; - init_rwsem(&pcc_data.pcc_lock); - init_waitqueue_head(&pcc_data.pcc_write_wait_q); + init_rwsem(&pcc_data[pcc_subspace_id]->pcc_lock); + init_waitqueue_head(&pcc_data[pcc_subspace_id]->pcc_write_wait_q); } /* Everything looks okay */ @@ -831,6 +871,18 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr) struct cpc_desc *cpc_ptr; unsigned int i; void __iomem *addr; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, pr->id); + + if (pcc_ss_id >=0 && pcc_data[pcc_ss_id]) { + if (pcc_data[pcc_ss_id]->pcc_channel_acquired) { + pcc_data[pcc_ss_id]->refcount--; + if (!pcc_data[pcc_ss_id]->refcount) { + pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel); + pcc_data[pcc_ss_id]->pcc_channel_acquired = 0; + kfree(pcc_data[pcc_ss_id]); + } + } + } cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); if (!cpc_ptr) @@ -888,6 +940,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) { int ret_val = 0; void __iomem *vaddr = 0; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; if (reg_res->type == ACPI_TYPE_INTEGER) { @@ -896,8 +949,8 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) } *val = 0; - if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) - vaddr = GET_PCC_VADDR(reg->address); + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) @@ -932,10 +985,11 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) { int ret_val = 0; void __iomem *vaddr = 0; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; - if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) - vaddr = GET_PCC_VADDR(reg->address); + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) @@ -980,13 +1034,16 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) struct cpc_register_resource *highest_reg, *lowest_reg, *lowest_non_linear_reg, *nominal_reg; u64 high, low, nom, min_nonlinear; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); + struct cppc_pcc_data *pcc_ss_data; int ret = 0, regs_in_pcc = 0; - if (!cpc_desc) { + if (!cpc_desc || pcc_ss_id < 0) { pr_debug("No CPC descriptor for CPU:%d\n", cpunum); return -ENODEV; } + pcc_ss_data = pcc_data[pcc_ss_id]; highest_reg = &cpc_desc->cpc_regs[HIGHEST_PERF]; lowest_reg = &cpc_desc->cpc_regs[LOWEST_PERF]; lowest_non_linear_reg = &cpc_desc->cpc_regs[LOW_NON_LINEAR_PERF]; @@ -996,9 +1053,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) { regs_in_pcc = 1; - down_write(&pcc_data.pcc_lock); + down_write(&pcc_ss_data->pcc_lock); /* Ring doorbell once to update PCC subspace */ - if (send_pcc_cmd(CMD_READ) < 0) { + if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) { ret = -EIO; goto out_err; } @@ -1021,7 +1078,7 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) out_err: if (regs_in_pcc) - up_write(&pcc_data.pcc_lock); + up_write(&pcc_ss_data->pcc_lock); return ret; } EXPORT_SYMBOL_GPL(cppc_get_perf_caps); @@ -1038,14 +1095,17 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); struct cpc_register_resource *delivered_reg, *reference_reg, *ref_perf_reg, *ctr_wrap_reg; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); + struct cppc_pcc_data *pcc_ss_data; u64 delivered, reference, ref_perf, ctr_wrap_time; int ret = 0, regs_in_pcc = 0; - if (!cpc_desc) { + if (!cpc_desc || pcc_ss_id < 0) { pr_debug("No CPC descriptor for CPU:%d\n", cpunum); return -ENODEV; } + pcc_ss_data = pcc_data[pcc_ss_id]; delivered_reg = &cpc_desc->cpc_regs[DELIVERED_CTR]; reference_reg = &cpc_desc->cpc_regs[REFERENCE_CTR]; ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF]; @@ -1061,10 +1121,10 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) /* Are any of the regs PCC ?*/ if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { - down_write(&pcc_data.pcc_lock); + down_write(&pcc_ss_data->pcc_lock); regs_in_pcc = 1; /* Ring doorbell once to update PCC subspace */ - if (send_pcc_cmd(CMD_READ) < 0) { + if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) { ret = -EIO; goto out_err; } @@ -1094,7 +1154,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) perf_fb_ctrs->wraparound_time = ctr_wrap_time; out_err: if (regs_in_pcc) - up_write(&pcc_data.pcc_lock); + up_write(&pcc_ss_data->pcc_lock); return ret; } EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); @@ -1110,13 +1170,16 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) { struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); struct cpc_register_resource *desired_reg; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); + struct cppc_pcc_data *pcc_ss_data; int ret = 0; - if (!cpc_desc) { + if (!cpc_desc || pcc_ss_id < 0) { pr_debug("No CPC descriptor for CPU:%d\n", cpu); return -ENODEV; } + pcc_ss_data = pcc_data[pcc_ss_id]; desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; /* @@ -1127,11 +1190,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) * achieve that goal here */ if (CPC_IN_PCC(desired_reg)) { - down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */ - if (pcc_data.platform_owns_pcc) { - ret = check_pcc_chan(false); + down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ + if (pcc_ss_data->platform_owns_pcc) { + ret = check_pcc_chan(pcc_ss_id, false); if (ret) { - up_read(&pcc_data.pcc_lock); + up_read(&pcc_ss_data->pcc_lock); return ret; } } @@ -1139,8 +1202,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) * Update the pending_write to make sure a PCC CMD_READ will not * arrive and steal the channel during the switch to write lock */ - pcc_data.pending_pcc_write_cmd = true; - cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt; + pcc_ss_data->pending_pcc_write_cmd = true; + cpc_desc->write_cmd_id = pcc_ss_data->pcc_write_cnt; cpc_desc->write_cmd_status = 0; } @@ -1151,7 +1214,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) cpc_write(cpu, desired_reg, perf_ctrls->desired_perf); if (CPC_IN_PCC(desired_reg)) - up_read(&pcc_data.pcc_lock); /* END Phase-I */ + up_read(&pcc_ss_data->pcc_lock); /* END Phase-I */ /* * This is Phase-II where we transfer the ownership of PCC to Platform * @@ -1199,15 +1262,15 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) * the write command before servicing the read command */ if (CPC_IN_PCC(desired_reg)) { - if (down_write_trylock(&pcc_data.pcc_lock)) { /* BEGIN Phase-II */ + if (down_write_trylock(&pcc_ss_data->pcc_lock)) {/* BEGIN Phase-II */ /* Update only if there are pending write commands */ - if (pcc_data.pending_pcc_write_cmd) - send_pcc_cmd(CMD_WRITE); - up_write(&pcc_data.pcc_lock); /* END Phase-II */ + if (pcc_ss_data->pending_pcc_write_cmd) + send_pcc_cmd(pcc_ss_id, CMD_WRITE); + up_write(&pcc_ss_data->pcc_lock); /* END Phase-II */ } else /* Wait until pcc_write_cnt is updated by send_pcc_cmd */ - wait_event(pcc_data.pcc_write_wait_q, - cpc_desc->write_cmd_id != pcc_data.pcc_write_cnt); + wait_event(pcc_ss_data->pcc_write_wait_q, + cpc_desc->write_cmd_id != pcc_ss_data->pcc_write_cnt); /* send_pcc_cmd updates the status in case of failure */ ret = cpc_desc->write_cmd_status; @@ -1240,6 +1303,8 @@ unsigned int cppc_get_transition_latency(int cpu_num) unsigned int latency_ns = 0; struct cpc_desc *cpc_desc; struct cpc_register_resource *desired_reg; + int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu_num); + struct cppc_pcc_data *pcc_ss_data; cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); if (!cpc_desc) @@ -1249,11 +1314,15 @@ unsigned int cppc_get_transition_latency(int cpu_num) if (!CPC_IN_PCC(desired_reg)) return CPUFREQ_ETERNAL; - if (pcc_data.pcc_mpar) - latency_ns = 60 * (1000 * 1000 * 1000 / pcc_data.pcc_mpar); + if (pcc_ss_id < 0) + return CPUFREQ_ETERNAL; + + pcc_ss_data = pcc_data[pcc_ss_id]; + if (pcc_ss_data->pcc_mpar) + latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar); - latency_ns = max(latency_ns, pcc_data.pcc_nominal * 1000); - latency_ns = max(latency_ns, pcc_data.pcc_mrtt * 1000); + latency_ns = max(latency_ns, pcc_ss_data->pcc_nominal * 1000); + latency_ns = max(latency_ns, pcc_ss_data->pcc_mrtt * 1000); return latency_ns; } diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index fbcc73f7a099..c4d0a1c912f0 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -387,6 +387,7 @@ EXPORT_SYMBOL(acpi_bus_power_manageable); #ifdef CONFIG_PM static DEFINE_MUTEX(acpi_pm_notifier_lock); +static DEFINE_MUTEX(acpi_pm_notifier_install_lock); void acpi_pm_wakeup_event(struct device *dev) { @@ -443,24 +444,25 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, if (!dev && !func) return AE_BAD_PARAMETER; - mutex_lock(&acpi_pm_notifier_lock); + mutex_lock(&acpi_pm_notifier_install_lock); if (adev->wakeup.flags.notifier_present) goto out; - adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); - adev->wakeup.context.dev = dev; - adev->wakeup.context.func = func; - status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, acpi_pm_notify_handler, NULL); if (ACPI_FAILURE(status)) goto out; + mutex_lock(&acpi_pm_notifier_lock); + adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); + adev->wakeup.context.dev = dev; + adev->wakeup.context.func = func; adev->wakeup.flags.notifier_present = true; + mutex_unlock(&acpi_pm_notifier_lock); out: - mutex_unlock(&acpi_pm_notifier_lock); + mutex_unlock(&acpi_pm_notifier_install_lock); return status; } @@ -472,7 +474,7 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) { acpi_status status = AE_BAD_PARAMETER; - mutex_lock(&acpi_pm_notifier_lock); + mutex_lock(&acpi_pm_notifier_install_lock); if (!adev->wakeup.flags.notifier_present) goto out; @@ -483,14 +485,15 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) if (ACPI_FAILURE(status)) goto out; + mutex_lock(&acpi_pm_notifier_lock); adev->wakeup.context.func = NULL; adev->wakeup.context.dev = NULL; wakeup_source_unregister(adev->wakeup.ws); - adev->wakeup.flags.notifier_present = false; + mutex_unlock(&acpi_pm_notifier_lock); out: - mutex_unlock(&acpi_pm_notifier_lock); + mutex_unlock(&acpi_pm_notifier_install_lock); return status; } @@ -581,8 +584,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, d_min = ret; wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid && adev->wakeup.sleep_state >= target_state; - } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != - PM_QOS_FLAGS_NONE) { + } else { wakeup = adev->wakeup.flags.valid; } @@ -848,48 +850,48 @@ static int acpi_dev_pm_full_power(struct acpi_device *adev) } /** - * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI. + * acpi_dev_suspend - Put device into a low-power state using ACPI. * @dev: Device to put into a low-power state. + * @wakeup: Whether or not to enable wakeup for the device. * - * Put the given device into a runtime low-power state using the standard ACPI + * Put the given device into a low-power state using the standard ACPI * mechanism. Set up remote wakeup if desired, choose the state to put the * device into (this checks if remote wakeup is expected to work too), and set * the power state of the device. */ -int acpi_dev_runtime_suspend(struct device *dev) +int acpi_dev_suspend(struct device *dev, bool wakeup) { struct acpi_device *adev = ACPI_COMPANION(dev); - bool remote_wakeup; + u32 target_state = acpi_target_system_state(); int error; if (!adev) return 0; - remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) > - PM_QOS_FLAGS_NONE; - if (remote_wakeup) { - error = acpi_device_wakeup_enable(adev, ACPI_STATE_S0); + if (wakeup && acpi_device_can_wakeup(adev)) { + error = acpi_device_wakeup_enable(adev, target_state); if (error) return -EAGAIN; + } else { + wakeup = false; } - error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); - if (error && remote_wakeup) + error = acpi_dev_pm_low_power(dev, adev, target_state); + if (error && wakeup) acpi_device_wakeup_disable(adev); return error; } -EXPORT_SYMBOL_GPL(acpi_dev_runtime_suspend); +EXPORT_SYMBOL_GPL(acpi_dev_suspend); /** - * acpi_dev_runtime_resume - Put device into the full-power state using ACPI. + * acpi_dev_resume - Put device into the full-power state using ACPI. * @dev: Device to put into the full-power state. * * Put the given device into the full-power state using the standard ACPI - * mechanism at run time. Set the power state of the device to ACPI D0 and - * disable remote wakeup. + * mechanism. Set the power state of the device to ACPI D0 and disable wakeup. */ -int acpi_dev_runtime_resume(struct device *dev) +int acpi_dev_resume(struct device *dev) { struct acpi_device *adev = ACPI_COMPANION(dev); int error; @@ -901,7 +903,7 @@ int acpi_dev_runtime_resume(struct device *dev) acpi_device_wakeup_disable(adev); return error; } -EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume); +EXPORT_SYMBOL_GPL(acpi_dev_resume); /** * acpi_subsys_runtime_suspend - Suspend device using ACPI. @@ -913,7 +915,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume); int acpi_subsys_runtime_suspend(struct device *dev) { int ret = pm_generic_runtime_suspend(dev); - return ret ? ret : acpi_dev_runtime_suspend(dev); + return ret ? ret : acpi_dev_suspend(dev, true); } EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend); @@ -926,68 +928,33 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend); */ int acpi_subsys_runtime_resume(struct device *dev) { - int ret = acpi_dev_runtime_resume(dev); + int ret = acpi_dev_resume(dev); return ret ? ret : pm_generic_runtime_resume(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume); #ifdef CONFIG_PM_SLEEP -/** - * acpi_dev_suspend_late - Put device into a low-power state using ACPI. - * @dev: Device to put into a low-power state. - * - * Put the given device into a low-power state during system transition to a - * sleep state using the standard ACPI mechanism. Set up system wakeup if - * desired, choose the state to put the device into (this checks if system - * wakeup is expected to work too), and set the power state of the device. - */ -int acpi_dev_suspend_late(struct device *dev) +static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev) { - struct acpi_device *adev = ACPI_COMPANION(dev); - u32 target_state; - bool wakeup; - int error; - - if (!adev) - return 0; - - target_state = acpi_target_system_state(); - wakeup = device_may_wakeup(dev) && acpi_device_can_wakeup(adev); - if (wakeup) { - error = acpi_device_wakeup_enable(adev, target_state); - if (error) - return error; - } + u32 sys_target = acpi_target_system_state(); + int ret, state; - error = acpi_dev_pm_low_power(dev, adev, target_state); - if (error && wakeup) - acpi_device_wakeup_disable(adev); + if (!pm_runtime_suspended(dev) || !adev || + device_may_wakeup(dev) != !!adev->wakeup.prepare_count) + return true; - return error; -} -EXPORT_SYMBOL_GPL(acpi_dev_suspend_late); + if (sys_target == ACPI_STATE_S0) + return false; -/** - * acpi_dev_resume_early - Put device into the full-power state using ACPI. - * @dev: Device to put into the full-power state. - * - * Put the given device into the full-power state using the standard ACPI - * mechanism during system transition to the working state. Set the power - * state of the device to ACPI D0 and disable remote wakeup. - */ -int acpi_dev_resume_early(struct device *dev) -{ - struct acpi_device *adev = ACPI_COMPANION(dev); - int error; + if (adev->power.flags.dsw_present) + return true; - if (!adev) - return 0; + ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); + if (ret) + return true; - error = acpi_dev_pm_full_power(adev); - acpi_device_wakeup_disable(adev); - return error; + return state != adev->power.state; } -EXPORT_SYMBOL_GPL(acpi_dev_resume_early); /** * acpi_subsys_prepare - Prepare device for system transition to a sleep state. @@ -996,39 +963,53 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early); int acpi_subsys_prepare(struct device *dev) { struct acpi_device *adev = ACPI_COMPANION(dev); - u32 sys_target; - int ret, state; - ret = pm_generic_prepare(dev); - if (ret < 0) - return ret; + if (dev->driver && dev->driver->pm && dev->driver->pm->prepare) { + int ret = dev->driver->pm->prepare(dev); - if (!adev || !pm_runtime_suspended(dev) - || device_may_wakeup(dev) != !!adev->wakeup.prepare_count) - return 0; - - sys_target = acpi_target_system_state(); - if (sys_target == ACPI_STATE_S0) - return 1; + if (ret < 0) + return ret; - if (adev->power.flags.dsw_present) - return 0; + if (!ret && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE)) + return 0; + } - ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); - return !ret && state == adev->power.state; + return !acpi_dev_needs_resume(dev, adev); } EXPORT_SYMBOL_GPL(acpi_subsys_prepare); /** + * acpi_subsys_complete - Finalize device's resume during system resume. + * @dev: Device to handle. + */ +void acpi_subsys_complete(struct device *dev) +{ + pm_generic_complete(dev); + /* + * If the device had been runtime-suspended before the system went into + * the sleep state it is going out of and it has never been resumed till + * now, resume it in case the firmware powered it up. + */ + if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) + pm_request_resume(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_complete); + +/** * acpi_subsys_suspend - Run the device driver's suspend callback. * @dev: Device to handle. * - * Follow PCI and resume devices suspended at run time before running their - * system suspend callbacks. + * Follow PCI and resume devices from runtime suspend before running their + * system suspend 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_suspend(struct device *dev) { - pm_runtime_resume(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_suspend(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_suspend); @@ -1042,12 +1023,69 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend); */ int acpi_subsys_suspend_late(struct device *dev) { - int ret = pm_generic_suspend_late(dev); - return ret ? ret : acpi_dev_suspend_late(dev); + int ret; + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + ret = pm_generic_suspend_late(dev); + return ret ? ret : acpi_dev_suspend(dev, device_may_wakeup(dev)); } EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late); /** + * acpi_subsys_suspend_noirq - Run the device driver's "noirq" suspend callback. + * @dev: Device to suspend. + */ +int acpi_subsys_suspend_noirq(struct device *dev) +{ + int ret; + + if (dev_pm_smart_suspend_and_suspended(dev)) { + dev->power.may_skip_resume = true; + return 0; + } + + ret = pm_generic_suspend_noirq(dev); + if (ret) + return ret; + + /* + * If the target system sleep state is suspend-to-idle, it is sufficient + * to check whether or not the device's wakeup settings are good for + * runtime PM. Otherwise, the pm_resume_via_firmware() check will cause + * acpi_subsys_complete() to take care of fixing up the device's state + * anyway, if need be. + */ + dev->power.may_skip_resume = device_may_wakeup(dev) || + !device_can_wakeup(dev); + + return 0; +} +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) +{ + if (dev_pm_may_skip_resume(dev)) + return 0; + + /* + * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend + * during system suspend, so update their runtime PM status to "active" + * as they will be put into D0 going forward. + */ + if (dev_pm_smart_suspend_and_suspended(dev)) + pm_runtime_set_active(dev); + + return pm_generic_resume_noirq(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_resume_noirq); + +/** * acpi_subsys_resume_early - Resume device using ACPI. * @dev: Device to Resume. * @@ -1057,7 +1095,7 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late); */ int acpi_subsys_resume_early(struct device *dev) { - int ret = acpi_dev_resume_early(dev); + int ret = acpi_dev_resume(dev); return ret ? ret : pm_generic_resume_early(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); @@ -1074,11 +1112,60 @@ int acpi_subsys_freeze(struct device *dev) * runtime-suspended devices should not be touched during freeze/thaw * transitions. */ - pm_runtime_resume(dev); + if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) + 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. + */ +int acpi_subsys_freeze_late(struct device *dev) +{ + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + return pm_generic_freeze_late(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_freeze_late); + +/** + * acpi_subsys_freeze_noirq - Run the device driver's "noirq" freeze callback. + * @dev: Device to handle. + */ +int acpi_subsys_freeze_noirq(struct device *dev) +{ + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + + return pm_generic_freeze_noirq(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_freeze_noirq); + +/** + * acpi_subsys_thaw_noirq - Run the device driver's "noirq" thaw callback. + * @dev: Device to handle. + */ +int acpi_subsys_thaw_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); + return 0; + } + + return pm_generic_thaw_noirq(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_thaw_noirq); #endif /* CONFIG_PM_SLEEP */ static struct dev_pm_domain acpi_general_pm_domain = { @@ -1087,13 +1174,20 @@ static struct dev_pm_domain acpi_general_pm_domain = { .runtime_resume = acpi_subsys_runtime_resume, #ifdef CONFIG_PM_SLEEP .prepare = acpi_subsys_prepare, - .complete = pm_complete_with_resume_check, + .complete = acpi_subsys_complete, .suspend = acpi_subsys_suspend, .suspend_late = acpi_subsys_suspend_late, + .suspend_noirq = acpi_subsys_suspend_noirq, + .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, #endif }, diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 24418932612e..545e91420cde 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -146,6 +146,10 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias, int count; struct acpi_hardware_id *id; + /* Avoid unnecessarily loading modules for non present devices. */ + if (!acpi_device_is_present(acpi_dev)) + return 0; + /* * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the @@ -353,7 +357,7 @@ static ssize_t real_power_state_show(struct device *dev, return sprintf(buf, "%s\n", acpi_power_state_string(state)); } -static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL); +static DEVICE_ATTR_RO(real_power_state); static ssize_t power_state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -363,7 +367,7 @@ static ssize_t power_state_show(struct device *dev, return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); } -static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); +static DEVICE_ATTR_RO(power_state); static ssize_t acpi_eject_store(struct device *d, struct device_attribute *attr, @@ -458,7 +462,7 @@ static ssize_t description_show(struct device *dev, return result; } -static DEVICE_ATTR(description, 0444, description_show, NULL); +static DEVICE_ATTR_RO(description); static ssize_t acpi_device_sun_show(struct device *dev, struct device_attribute *attr, diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 2305e1ab978e..e3fc1f045e1c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -482,6 +482,7 @@ int dock_notify(struct acpi_device *adev, u32 event) surprise_removal = 1; event = ACPI_NOTIFY_EJECT_REQUEST; /* Fall back */ + /* fall through */ case ACPI_NOTIFY_EJECT_REQUEST: begin_undock(ds); if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 236b14324780..30a572956557 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -486,8 +486,11 @@ static inline void __acpi_ec_enable_event(struct acpi_ec *ec) { if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) ec_log_drv("event unblocked"); - if (!test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) - advance_transaction(ec); + /* + * Unconditionally invoke this once after enabling the event + * handling mechanism to detect the pending events. + */ + advance_transaction(ec); } static inline void __acpi_ec_disable_event(struct acpi_ec *ec) @@ -1456,11 +1459,10 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) if (test_bit(EC_FLAGS_STARTED, &ec->flags) && ec->reference_count >= 1) acpi_ec_enable_gpe(ec, true); - - /* EC is fully operational, allow queries */ - acpi_ec_enable_event(ec); } } + /* EC is fully operational, allow queries */ + acpi_ec_enable_event(ec); return 0; } @@ -1514,7 +1516,7 @@ static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events) } acpi_handle_info(ec->handle, - "GPE=0x%lx, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", + "GPE=0x%x, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); return ret; } @@ -1595,32 +1597,41 @@ static int acpi_ec_add(struct acpi_device *device) { struct acpi_ec *ec = NULL; int ret; + bool is_ecdt = false; + acpi_status status; strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); - ec = acpi_ec_alloc(); - if (!ec) - return -ENOMEM; - if (ec_parse_device(device->handle, 0, ec, NULL) != - AE_CTRL_TERMINATE) { + if (!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) { + is_ecdt = true; + ec = boot_ec; + } else { + ec = acpi_ec_alloc(); + if (!ec) + return -ENOMEM; + status = ec_parse_device(device->handle, 0, ec, NULL); + if (status != AE_CTRL_TERMINATE) { ret = -EINVAL; goto err_alloc; + } } if (acpi_is_boot_ec(ec)) { - boot_ec_is_ecdt = false; - /* - * Trust PNP0C09 namespace location rather than ECDT ID. - * - * But trust ECDT GPE rather than _GPE because of ASUS quirks, - * so do not change boot_ec->gpe to ec->gpe. - */ - boot_ec->handle = ec->handle; - acpi_handle_debug(ec->handle, "duplicated.\n"); - acpi_ec_free(ec); - ec = boot_ec; - ret = acpi_config_boot_ec(ec, ec->handle, true, false); + boot_ec_is_ecdt = is_ecdt; + if (!is_ecdt) { + /* + * Trust PNP0C09 namespace location rather than + * ECDT ID. But trust ECDT GPE rather than _GPE + * because of ASUS quirks, so do not change + * boot_ec->gpe to ec->gpe. + */ + boot_ec->handle = ec->handle; + acpi_handle_debug(ec->handle, "duplicated.\n"); + acpi_ec_free(ec); + ec = boot_ec; + } + ret = acpi_config_boot_ec(ec, ec->handle, true, is_ecdt); } else ret = acpi_ec_setup(ec, true); if (ret) @@ -1633,8 +1644,10 @@ static int acpi_ec_add(struct acpi_device *device) ret = !!request_region(ec->command_addr, 1, "EC cmd"); WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); - /* Reprobe devices depending on the EC */ - acpi_walk_dep_device_list(ec->handle); + if (!is_ecdt) { + /* Reprobe devices depending on the EC */ + acpi_walk_dep_device_list(ec->handle); + } acpi_handle_debug(ec->handle, "enumerated.\n"); return 0; @@ -1690,6 +1703,7 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) static const struct acpi_device_id ec_device_ids[] = { {"PNP0C09", 0}, + {ACPI_ECDT_HID, 0}, {"", 0}, }; @@ -1762,11 +1776,14 @@ static int __init acpi_ec_ecdt_start(void) * Note: ec->handle can be valid if this function is called after * acpi_ec_add(), hence the fast path. */ - if (boot_ec->handle != ACPI_ROOT_OBJECT) - handle = boot_ec->handle; - else if (!acpi_ec_ecdt_get_handle(&handle)) - return -ENODEV; - return acpi_config_boot_ec(boot_ec, handle, true, true); + if (boot_ec->handle == ACPI_ROOT_OBJECT) { + if (!acpi_ec_ecdt_get_handle(&handle)) + return -ENODEV; + boot_ec->handle = handle; + } + + /* Register to ACPI bus with PM ops attached */ + return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC); } #if 0 @@ -1910,6 +1927,9 @@ static int acpi_ec_suspend_noirq(struct device *dev) ec->reference_count >= 1) acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); + if (acpi_sleep_no_ec_events()) + acpi_ec_enter_noirq(ec); + return 0; } @@ -1917,6 +1937,9 @@ static int acpi_ec_resume_noirq(struct device *dev) { struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev)); + if (acpi_sleep_no_ec_events()) + acpi_ec_leave_noirq(ec); + if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) && ec->reference_count >= 1) acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); @@ -1939,7 +1962,8 @@ static const struct dev_pm_ops acpi_ec_pm = { SET_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend, acpi_ec_resume) }; -static int param_set_event_clearing(const char *val, struct kernel_param *kp) +static int param_set_event_clearing(const char *val, + const struct kernel_param *kp) { int result = 0; @@ -1957,7 +1981,8 @@ static int param_set_event_clearing(const char *val, struct kernel_param *kp) return result; } -static int param_get_event_clearing(char *buffer, struct kernel_param *kp) +static int param_get_event_clearing(char *buffer, + const struct kernel_param *kp) { switch (ec_event_clearing) { case ACPI_EC_EVT_TIMING_STATUS: @@ -2018,6 +2043,12 @@ int __init acpi_ec_init(void) /* Drivers must be started after acpi_ec_query_init() */ dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver); + /* + * Register ECDT to ACPI bus only when PNP0C09 probe fails. This is + * useful for platforms (confirmed on ASUS X550ZE) with valid ECDT + * settings but invalid DSDT settings. + * https://bugzilla.kernel.org/show_bug.cgi?id=196847 + */ ecdt_fail = acpi_ec_ecdt_start(); return ecdt_fail && dsdt_fail ? -ENODEV : 0; } diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 6c7dd7af789e..dd70d6c2bca0 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -128,7 +128,7 @@ static int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) return -ENOMEM; } - if (!debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe)) + if (!debugfs_create_x32("gpe", 0444, dev_dir, &first_ec->gpe)) goto error; if (!debugfs_create_bool("use_global_lock", 0444, dev_dir, &first_ec->global_lock)) diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c index 46f060356a22..f13ba2c07667 100644 --- a/drivers/acpi/evged.c +++ b/drivers/acpi/evged.c @@ -49,6 +49,11 @@ #define MODULE_NAME "acpi-ged" +struct acpi_ged_device { + struct device *dev; + struct list_head event_list; +}; + struct acpi_ged_event { struct list_head node; struct device *dev; @@ -76,7 +81,8 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, unsigned int irq; unsigned int gsi; unsigned int irqflags = IRQF_ONESHOT; - struct device *dev = context; + struct acpi_ged_device *geddev = context; + struct device *dev = geddev->dev; acpi_handle handle = ACPI_HANDLE(dev); acpi_handle evt_handle; struct resource r; @@ -102,8 +108,6 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, return AE_ERROR; } - dev_info(dev, "GED listening GSI %u @ IRQ %u\n", gsi, irq); - event = devm_kzalloc(dev, sizeof(*event), GFP_KERNEL); if (!event) return AE_ERROR; @@ -116,29 +120,58 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, if (r.flags & IORESOURCE_IRQ_SHAREABLE) irqflags |= IRQF_SHARED; - if (devm_request_threaded_irq(dev, irq, NULL, acpi_ged_irq_handler, - irqflags, "ACPI:Ged", event)) { + if (request_threaded_irq(irq, NULL, acpi_ged_irq_handler, + irqflags, "ACPI:Ged", event)) { dev_err(dev, "failed to setup event handler for irq %u\n", irq); return AE_ERROR; } + dev_dbg(dev, "GED listening GSI %u @ IRQ %u\n", gsi, irq); + list_add_tail(&event->node, &geddev->event_list); return AE_OK; } static int ged_probe(struct platform_device *pdev) { + struct acpi_ged_device *geddev; acpi_status acpi_ret; + geddev = devm_kzalloc(&pdev->dev, sizeof(*geddev), GFP_KERNEL); + if (!geddev) + return -ENOMEM; + + geddev->dev = &pdev->dev; + INIT_LIST_HEAD(&geddev->event_list); acpi_ret = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), "_CRS", - acpi_ged_request_interrupt, &pdev->dev); + acpi_ged_request_interrupt, geddev); if (ACPI_FAILURE(acpi_ret)) { dev_err(&pdev->dev, "unable to parse the _CRS record\n"); return -EINVAL; } + platform_set_drvdata(pdev, geddev); return 0; } +static void ged_shutdown(struct platform_device *pdev) +{ + struct acpi_ged_device *geddev = platform_get_drvdata(pdev); + struct acpi_ged_event *event, *next; + + list_for_each_entry_safe(event, next, &geddev->event_list, node) { + free_irq(event->irq, event); + list_del(&event->node); + dev_dbg(geddev->dev, "GED releasing GSI %u @ IRQ %u\n", + event->gsi, event->irq); + } +} + +static int ged_remove(struct platform_device *pdev) +{ + ged_shutdown(pdev); + return 0; +} + static const struct acpi_device_id ged_acpi_ids[] = { {"ACPI0013"}, {}, @@ -146,6 +179,8 @@ static const struct acpi_device_id ged_acpi_ids[] = { static struct platform_driver ged_driver = { .probe = ged_probe, + .remove = ged_remove, + .shutdown = ged_shutdown, .driver = { .name = MODULE_NAME, .acpi_match_table = ACPI_PTR(ged_acpi_ids), diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4361c4415b4f..1d0a501bc7f0 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -115,6 +115,7 @@ bool acpi_device_is_present(const struct acpi_device *adev); bool acpi_device_is_battery(struct acpi_device *adev); bool acpi_device_is_first_physical_node(struct acpi_device *adev, const struct device *dev); +int acpi_bus_register_early_device(int type); /* -------------------------------------------------------------------------- Device Matching and Notification @@ -158,7 +159,7 @@ static inline void acpi_early_processor_osc(void) {} -------------------------------------------------------------------------- */ struct acpi_ec { acpi_handle handle; - unsigned long gpe; + u32 gpe; unsigned long command_addr; unsigned long data_addr; bool global_lock; @@ -248,4 +249,10 @@ void acpi_watchdog_init(void); static inline void acpi_watchdog_init(void) {} #endif +#ifdef CONFIG_ACPI_LPIT +void acpi_init_lpit(void); +#else +static inline void acpi_init_lpit(void) { } +#endif + #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 9c2c49b6a240..bbe48ad20886 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -183,13 +183,33 @@ static int xlat_bus_status(void *buf, unsigned int cmd, u32 status) return 0; } -static int xlat_nvdimm_status(void *buf, unsigned int cmd, u32 status) +#define ACPI_LABELS_LOCKED 3 + +static int xlat_nvdimm_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd, + u32 status) { + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); + switch (cmd) { case ND_CMD_GET_CONFIG_SIZE: + /* + * In the _LSI, _LSR, _LSW case the locked status is + * communicated via the read/write commands + */ + if (nfit_mem->has_lsi) + break; + if (status >> 16 & ND_CONFIG_LOCKED) return -EACCES; break; + case ND_CMD_GET_CONFIG_DATA: + if (nfit_mem->has_lsr && status == ACPI_LABELS_LOCKED) + return -EACCES; + break; + case ND_CMD_SET_CONFIG_DATA: + if (nfit_mem->has_lsw && status == ACPI_LABELS_LOCKED) + return -EACCES; + break; default: break; } @@ -205,13 +225,182 @@ static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd, { if (!nvdimm) return xlat_bus_status(buf, cmd, status); - return xlat_nvdimm_status(buf, cmd, status); + return xlat_nvdimm_status(nvdimm, buf, cmd, status); +} + +/* convert _LS{I,R} packages to the buffer object acpi_nfit_ctl expects */ +static union acpi_object *pkg_to_buf(union acpi_object *pkg) +{ + int i; + void *dst; + size_t size = 0; + union acpi_object *buf = NULL; + + if (pkg->type != ACPI_TYPE_PACKAGE) { + WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n", + pkg->type); + goto err; + } + + for (i = 0; i < pkg->package.count; i++) { + union acpi_object *obj = &pkg->package.elements[i]; + + if (obj->type == ACPI_TYPE_INTEGER) + size += 4; + else if (obj->type == ACPI_TYPE_BUFFER) + size += obj->buffer.length; + else { + WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n", + obj->type); + goto err; + } + } + + buf = ACPI_ALLOCATE(sizeof(*buf) + size); + if (!buf) + goto err; + + dst = buf + 1; + buf->type = ACPI_TYPE_BUFFER; + buf->buffer.length = size; + buf->buffer.pointer = dst; + for (i = 0; i < pkg->package.count; i++) { + union acpi_object *obj = &pkg->package.elements[i]; + + if (obj->type == ACPI_TYPE_INTEGER) { + memcpy(dst, &obj->integer.value, 4); + dst += 4; + } else if (obj->type == ACPI_TYPE_BUFFER) { + memcpy(dst, obj->buffer.pointer, obj->buffer.length); + dst += obj->buffer.length; + } + } +err: + ACPI_FREE(pkg); + return buf; +} + +static union acpi_object *int_to_buf(union acpi_object *integer) +{ + union acpi_object *buf = ACPI_ALLOCATE(sizeof(*buf) + 4); + void *dst = NULL; + + if (!buf) + goto err; + + if (integer->type != ACPI_TYPE_INTEGER) { + WARN_ONCE(1, "BIOS bug, unexpected element type: %d\n", + integer->type); + goto err; + } + + dst = buf + 1; + buf->type = ACPI_TYPE_BUFFER; + buf->buffer.length = 4; + buf->buffer.pointer = dst; + memcpy(dst, &integer->integer.value, 4); +err: + ACPI_FREE(integer); + return buf; +} + +static union acpi_object *acpi_label_write(acpi_handle handle, u32 offset, + u32 len, void *data) +{ + acpi_status rc; + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input = { + .count = 3, + .pointer = (union acpi_object []) { + [0] = { + .integer.type = ACPI_TYPE_INTEGER, + .integer.value = offset, + }, + [1] = { + .integer.type = ACPI_TYPE_INTEGER, + .integer.value = len, + }, + [2] = { + .buffer.type = ACPI_TYPE_BUFFER, + .buffer.pointer = data, + .buffer.length = len, + }, + }, + }; + + rc = acpi_evaluate_object(handle, "_LSW", &input, &buf); + if (ACPI_FAILURE(rc)) + return NULL; + return int_to_buf(buf.pointer); +} + +static union acpi_object *acpi_label_read(acpi_handle handle, u32 offset, + u32 len) +{ + acpi_status rc; + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input = { + .count = 2, + .pointer = (union acpi_object []) { + [0] = { + .integer.type = ACPI_TYPE_INTEGER, + .integer.value = offset, + }, + [1] = { + .integer.type = ACPI_TYPE_INTEGER, + .integer.value = len, + }, + }, + }; + + rc = acpi_evaluate_object(handle, "_LSR", &input, &buf); + if (ACPI_FAILURE(rc)) + return NULL; + return pkg_to_buf(buf.pointer); +} + +static union acpi_object *acpi_label_info(acpi_handle handle) +{ + acpi_status rc; + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + + rc = acpi_evaluate_object(handle, "_LSI", NULL, &buf); + if (ACPI_FAILURE(rc)) + return NULL; + return pkg_to_buf(buf.pointer); +} + +static u8 nfit_dsm_revid(unsigned family, unsigned func) +{ + static const u8 revid_table[NVDIMM_FAMILY_MAX+1][32] = { + [NVDIMM_FAMILY_INTEL] = { + [NVDIMM_INTEL_GET_MODES] = 2, + [NVDIMM_INTEL_GET_FWINFO] = 2, + [NVDIMM_INTEL_START_FWUPDATE] = 2, + [NVDIMM_INTEL_SEND_FWUPDATE] = 2, + [NVDIMM_INTEL_FINISH_FWUPDATE] = 2, + [NVDIMM_INTEL_QUERY_FWUPDATE] = 2, + [NVDIMM_INTEL_SET_THRESHOLD] = 2, + [NVDIMM_INTEL_INJECT_ERROR] = 2, + }, + }; + u8 id; + + if (family > NVDIMM_FAMILY_MAX) + return 0; + if (func > 31) + return 0; + id = revid_table[family][func]; + if (id == 0) + return 1; /* default */ + return id; } int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc) { struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc); + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); union acpi_object in_obj, in_buf, *out_obj; const struct nd_cmd_desc *desc = NULL; struct device *dev = acpi_desc->dev; @@ -235,7 +424,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, } if (nvdimm) { - struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); struct acpi_device *adev = nfit_mem->adev; if (!adev) @@ -294,7 +482,29 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, in_buf.buffer.pointer, min_t(u32, 256, in_buf.buffer.length), true); - out_obj = acpi_evaluate_dsm(handle, guid, 1, func, &in_obj); + /* call the BIOS, prefer the named methods over _DSM if available */ + if (nvdimm && cmd == ND_CMD_GET_CONFIG_SIZE && nfit_mem->has_lsi) + out_obj = acpi_label_info(handle); + else if (nvdimm && cmd == ND_CMD_GET_CONFIG_DATA && nfit_mem->has_lsr) { + struct nd_cmd_get_config_data_hdr *p = buf; + + out_obj = acpi_label_read(handle, p->in_offset, p->in_length); + } else if (nvdimm && cmd == ND_CMD_SET_CONFIG_DATA + && nfit_mem->has_lsw) { + struct nd_cmd_set_config_hdr *p = buf; + + out_obj = acpi_label_write(handle, p->in_offset, p->in_length, + p->in_buf); + } else { + u8 revid; + + if (nvdimm) + revid = nfit_dsm_revid(nfit_mem->family, func); + else + revid = 1; + out_obj = acpi_evaluate_dsm(handle, guid, revid, func, &in_obj); + } + if (!out_obj) { dev_dbg(dev, "%s:%s _DSM failed cmd: %s\n", __func__, dimm_name, cmd_name); @@ -356,8 +566,10 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, * Set fw_status for all the commands with a known format to be * later interpreted by xlat_status(). */ - if (i >= 1 && ((cmd >= ND_CMD_ARS_CAP && cmd <= ND_CMD_CLEAR_ERROR) - || (cmd >= ND_CMD_SMART && cmd <= ND_CMD_VENDOR))) + if (i >= 1 && ((!nvdimm && cmd >= ND_CMD_ARS_CAP + && cmd <= ND_CMD_CLEAR_ERROR) + || (nvdimm && cmd >= ND_CMD_SMART + && cmd <= ND_CMD_VENDOR))) fw_status = *(u32 *) out_obj->buffer.pointer; if (offset + in_buf.buffer.length < buf_len) { @@ -626,6 +838,18 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc, return true; } +static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc, + struct acpi_nfit_capabilities *pcap) +{ + struct device *dev = acpi_desc->dev; + u32 mask; + + mask = (1 << (pcap->highest_capability + 1)) - 1; + acpi_desc->platform_cap = pcap->capabilities & mask; + dev_dbg(dev, "%s: cap: %#x\n", __func__, acpi_desc->platform_cap); + return true; +} + static void *add_table(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, void *table, const void *end) { @@ -671,6 +895,10 @@ static void *add_table(struct acpi_nfit_desc *acpi_desc, case ACPI_NFIT_TYPE_SMBIOS: dev_dbg(dev, "%s: smbios\n", __func__); break; + case ACPI_NFIT_TYPE_CAPABILITIES: + if (!add_platform_cap(acpi_desc, table)) + return err; + break; default: dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type); break; @@ -1431,6 +1659,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, { struct acpi_device *adev, *adev_dimm; struct device *dev = acpi_desc->dev; + union acpi_object *obj; unsigned long dsm_mask; const guid_t *guid; int i; @@ -1457,13 +1686,18 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, dev_name(&adev_dimm->dev)); return -ENXIO; } + /* + * Record nfit_mem for the notification path to track back to + * the nfit sysfs attributes for this dimm device object. + */ + dev_set_drvdata(&adev_dimm->dev, nfit_mem); /* * Until standardization materializes we need to consider 4 * different command sets. Note, that checking for function0 (bit0) * tells us if any commands are reachable through this GUID. */ - for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_MSFT; i++) + for (i = 0; i <= NVDIMM_FAMILY_MAX; i++) if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1)) if (family < 0 || i == default_dsm_family) family = i; @@ -1473,7 +1707,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, if (override_dsm_mask && !disable_vendor_specific) dsm_mask = override_dsm_mask; else if (nfit_mem->family == NVDIMM_FAMILY_INTEL) { - dsm_mask = 0x3fe; + dsm_mask = NVDIMM_INTEL_CMDMASK; if (disable_vendor_specific) dsm_mask &= ~(1 << ND_CMD_VENDOR); } else if (nfit_mem->family == NVDIMM_FAMILY_HPE1) { @@ -1493,9 +1727,32 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, guid = to_nfit_uuid(nfit_mem->family); for_each_set_bit(i, &dsm_mask, BITS_PER_LONG) - if (acpi_check_dsm(adev_dimm->handle, guid, 1, 1ULL << i)) + if (acpi_check_dsm(adev_dimm->handle, guid, + nfit_dsm_revid(nfit_mem->family, i), + 1ULL << i)) set_bit(i, &nfit_mem->dsm_mask); + obj = acpi_label_info(adev_dimm->handle); + if (obj) { + ACPI_FREE(obj); + nfit_mem->has_lsi = 1; + dev_dbg(dev, "%s: has _LSI\n", dev_name(&adev_dimm->dev)); + } + + obj = acpi_label_read(adev_dimm->handle, 0, 0); + if (obj) { + ACPI_FREE(obj); + nfit_mem->has_lsr = 1; + dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev)); + } + + obj = acpi_label_write(adev_dimm->handle, 0, 0, NULL); + if (obj) { + ACPI_FREE(obj); + nfit_mem->has_lsw = 1; + dev_dbg(dev, "%s: has _LSW\n", dev_name(&adev_dimm->dev)); + } + return 0; } @@ -1516,9 +1773,11 @@ static void shutdown_dimm_notify(void *data) sysfs_put(nfit_mem->flags_attr); nfit_mem->flags_attr = NULL; } - if (adev_dimm) + if (adev_dimm) { acpi_remove_notify_handler(adev_dimm->handle, ACPI_DEVICE_NOTIFY, acpi_nvdimm_notify); + dev_set_drvdata(&adev_dimm->dev, NULL); + } } mutex_unlock(&acpi_desc->init_mutex); } @@ -1571,8 +1830,21 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) * userspace interface. */ cmd_mask = 1UL << ND_CMD_CALL; - if (nfit_mem->family == NVDIMM_FAMILY_INTEL) - cmd_mask |= nfit_mem->dsm_mask; + if (nfit_mem->family == NVDIMM_FAMILY_INTEL) { + /* + * These commands have a 1:1 correspondence + * between DSM payload and libnvdimm ioctl + * payload format. + */ + cmd_mask |= nfit_mem->dsm_mask & NVDIMM_STANDARD_CMDMASK; + } + + if (nfit_mem->has_lsi) + set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask); + if (nfit_mem->has_lsr) + set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask); + if (nfit_mem->has_lsw) + set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask); flush = nfit_mem->nfit_flush ? nfit_mem->nfit_flush->flush : NULL; @@ -1611,6 +1883,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) struct kernfs_node *nfit_kernfs; nvdimm = nfit_mem->nvdimm; + if (!nvdimm) + continue; + nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit"); if (nfit_kernfs) nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs, @@ -1645,6 +1920,7 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc) int i; nd_desc->cmd_mask = acpi_desc->bus_cmd_force_en; + nd_desc->bus_dsm_mask = acpi_desc->bus_nfit_cmd_force_en; adev = to_acpi_dev(acpi_desc); if (!adev) return; @@ -2239,7 +2515,7 @@ static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc, if (ars_status->out_length < 44 + sizeof(struct nd_ars_record) * (i + 1)) break; - rc = nvdimm_bus_add_poison(nvdimm_bus, + rc = nvdimm_bus_add_badrange(nvdimm_bus, ars_status->records[i].err_address, ars_status->records[i].length); if (rc) @@ -2399,6 +2675,12 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, else ndr_desc->numa_node = NUMA_NO_NODE; + if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH) + set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags); + + if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH) + set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags); + list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev; struct nd_mapping_desc *mapping; @@ -3207,6 +3489,7 @@ static __init int nfit_init(void) BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9); BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80); BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40); + BUILD_BUG_ON(sizeof(struct acpi_nfit_capabilities) != 16); guid_parse(UUID_VOLATILE_MEMORY, &nfit_uuid[NFIT_SPA_VOLATILE]); guid_parse(UUID_PERSISTENT_MEMORY, &nfit_uuid[NFIT_SPA_PM]); diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c index feeb95d574fa..b92921439657 100644 --- a/drivers/acpi/nfit/mce.c +++ b/drivers/acpi/nfit/mce.c @@ -67,7 +67,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, continue; /* If this fails due to an -ENOMEM, there is little we can do */ - nvdimm_bus_add_poison(acpi_desc->nvdimm_bus, + nvdimm_bus_add_badrange(acpi_desc->nvdimm_bus, ALIGN(mce->addr, L1_CACHE_BYTES), L1_CACHE_BYTES); nvdimm_region_notify(nfit_spa->nd_region, diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index 54292db61262..50d36e166d70 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -24,7 +24,7 @@ /* ACPI 6.1 */ #define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba" -/* http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf */ +/* http://pmem.io/documents/NVDIMM_DSM_Interface-V1.6.pdf */ #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" /* https://github.com/HewlettPackard/hpe-nvm/blob/master/Documentation/ */ @@ -38,6 +38,37 @@ | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED) +#define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_MSFT + +#define NVDIMM_STANDARD_CMDMASK \ +(1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \ + | 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA \ + | 1 << ND_CMD_SET_CONFIG_DATA | 1 << ND_CMD_VENDOR_EFFECT_LOG_SIZE \ + | 1 << ND_CMD_VENDOR_EFFECT_LOG | 1 << ND_CMD_VENDOR) + +/* + * Command numbers that the kernel needs to know about to handle + * non-default DSM revision ids + */ +enum nvdimm_family_cmds { + NVDIMM_INTEL_LATCH_SHUTDOWN = 10, + NVDIMM_INTEL_GET_MODES = 11, + NVDIMM_INTEL_GET_FWINFO = 12, + NVDIMM_INTEL_START_FWUPDATE = 13, + NVDIMM_INTEL_SEND_FWUPDATE = 14, + NVDIMM_INTEL_FINISH_FWUPDATE = 15, + NVDIMM_INTEL_QUERY_FWUPDATE = 16, + NVDIMM_INTEL_SET_THRESHOLD = 17, + NVDIMM_INTEL_INJECT_ERROR = 18, +}; + +#define NVDIMM_INTEL_CMDMASK \ +(NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \ + | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \ + | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \ + | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \ + | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN) + enum nfit_uuids { /* for simplicity alias the uuid index with the family id */ NFIT_DEV_DIMM = NVDIMM_FAMILY_INTEL, @@ -140,6 +171,9 @@ struct nfit_mem { struct resource *flush_wpq; unsigned long dsm_mask; int family; + u32 has_lsi:1; + u32 has_lsr:1; + u32 has_lsw:1; }; struct acpi_nfit_desc { @@ -167,6 +201,8 @@ struct acpi_nfit_desc { unsigned int init_complete:1; unsigned long dimm_cmd_force_en; unsigned long bus_cmd_force_en; + unsigned long bus_nfit_cmd_force_en; + unsigned int platform_cap; int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa, void *iobuf, u64 len, int rw); }; diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 917f1cc0fda4..8ccaae3550d2 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -460,8 +460,7 @@ int __init acpi_numa_init(void) srat_proc, ARRAY_SIZE(srat_proc), 0); cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, - acpi_parse_memory_affinity, - NR_NODE_MEMBLKS); + acpi_parse_memory_affinity, 0); } /* SLIT: System Locality Information Table */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index db78d353bab1..3bb46cb24a99 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -663,6 +663,29 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) EXPORT_SYMBOL(acpi_os_write_port); +int acpi_os_read_iomem(void __iomem *virt_addr, u64 *value, u32 width) +{ + + switch (width) { + case 8: + *(u8 *) value = readb(virt_addr); + break; + case 16: + *(u16 *) value = readw(virt_addr); + break; + case 32: + *(u32 *) value = readl(virt_addr); + break; + case 64: + *(u64 *) value = readq(virt_addr); + break; + default: + return -EINVAL; + } + + return 0; +} + acpi_status acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) { @@ -670,6 +693,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) unsigned int size = width / 8; bool unmap = false; u64 dummy; + int error; rcu_read_lock(); virt_addr = acpi_map_vaddr_lookup(phys_addr, size); @@ -684,22 +708,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) if (!value) value = &dummy; - switch (width) { - case 8: - *(u8 *) value = readb(virt_addr); - break; - case 16: - *(u16 *) value = readw(virt_addr); - break; - case 32: - *(u32 *) value = readl(virt_addr); - break; - case 64: - *(u64 *) value = readq(virt_addr); - break; - default: - BUG(); - } + error = acpi_os_read_iomem(virt_addr, value, width); + BUG_ON(error); if (unmap) iounmap(virt_addr); diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index bc3d914dfc3e..85ad679390e3 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -612,7 +612,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) acpi_isa_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; - printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", + pr_info("%s [%s] enabled at IRQ %d\n", acpi_device_name(link->device), acpi_device_bid(link->device), link->irq.active); } diff --git a/drivers/acpi/pmic/intel_pmic_bxtwc.c b/drivers/acpi/pmic/intel_pmic_bxtwc.c index 90011aad4d20..886ac8b93cd0 100644 --- a/drivers/acpi/pmic/intel_pmic_bxtwc.c +++ b/drivers/acpi/pmic/intel_pmic_bxtwc.c @@ -400,7 +400,7 @@ static int intel_bxtwc_pmic_opregion_probe(struct platform_device *pdev) &intel_bxtwc_pmic_opregion_data); } -static struct platform_device_id bxt_wc_opregion_id_table[] = { +static const struct platform_device_id bxt_wc_opregion_id_table[] = { { .name = "bxt_wcove_region" }, {}, }; @@ -412,9 +412,4 @@ static struct platform_driver intel_bxtwc_pmic_opregion_driver = { }, .id_table = bxt_wc_opregion_id_table, }; - -static int __init intel_bxtwc_pmic_opregion_driver_init(void) -{ - return platform_driver_register(&intel_bxtwc_pmic_opregion_driver); -} -device_initcall(intel_bxtwc_pmic_opregion_driver_init); +builtin_platform_driver(intel_bxtwc_pmic_opregion_driver); diff --git a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c new file mode 100644 index 000000000000..f6d73a243d80 --- /dev/null +++ b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c @@ -0,0 +1,134 @@ +/* + * Dollar Cove TI PMIC operation region driver + * Copyright (C) 2014 Intel Corporation. All rights reserved. + * + * Rewritten and cleaned up + * Copyright (C) 2017 Takashi Iwai <tiwai@suse.de> + */ + +#include <linux/acpi.h> +#include <linux/init.h> +#include <linux/mfd/intel_soc_pmic.h> +#include <linux/platform_device.h> +#include "intel_pmic.h" + +/* registers stored in 16bit BE (high:low, total 10bit) */ +#define CHTDC_TI_VBAT 0x54 +#define CHTDC_TI_DIETEMP 0x56 +#define CHTDC_TI_BPTHERM 0x58 +#define CHTDC_TI_GPADC 0x5a + +static struct pmic_table chtdc_ti_power_table[] = { + { .address = 0x00, .reg = 0x41 }, + { .address = 0x04, .reg = 0x42 }, + { .address = 0x08, .reg = 0x43 }, + { .address = 0x0c, .reg = 0x45 }, + { .address = 0x10, .reg = 0x46 }, + { .address = 0x14, .reg = 0x47 }, + { .address = 0x18, .reg = 0x48 }, + { .address = 0x1c, .reg = 0x49 }, + { .address = 0x20, .reg = 0x4a }, + { .address = 0x24, .reg = 0x4b }, + { .address = 0x28, .reg = 0x4c }, + { .address = 0x2c, .reg = 0x4d }, + { .address = 0x30, .reg = 0x4e }, +}; + +static struct pmic_table chtdc_ti_thermal_table[] = { + { + .address = 0x00, + .reg = CHTDC_TI_GPADC + }, + { + .address = 0x0c, + .reg = CHTDC_TI_GPADC + }, + /* TMP2 -> SYSTEMP */ + { + .address = 0x18, + .reg = CHTDC_TI_GPADC + }, + /* TMP3 -> BPTHERM */ + { + .address = 0x24, + .reg = CHTDC_TI_BPTHERM + }, + { + .address = 0x30, + .reg = CHTDC_TI_GPADC + }, + /* TMP5 -> DIETEMP */ + { + .address = 0x3c, + .reg = CHTDC_TI_DIETEMP + }, +}; + +static int chtdc_ti_pmic_get_power(struct regmap *regmap, int reg, int bit, + u64 *value) +{ + int data; + + if (regmap_read(regmap, reg, &data)) + return -EIO; + + *value = data & 1; + return 0; +} + +static int chtdc_ti_pmic_update_power(struct regmap *regmap, int reg, int bit, + bool on) +{ + return regmap_update_bits(regmap, reg, 1, on); +} + +static int chtdc_ti_pmic_get_raw_temp(struct regmap *regmap, int reg) +{ + u8 buf[2]; + + if (regmap_bulk_read(regmap, reg, buf, 2)) + return -EIO; + + /* stored in big-endian */ + return ((buf[0] & 0x03) << 8) | buf[1]; +} + +static struct intel_pmic_opregion_data chtdc_ti_pmic_opregion_data = { + .get_power = chtdc_ti_pmic_get_power, + .update_power = chtdc_ti_pmic_update_power, + .get_raw_temp = chtdc_ti_pmic_get_raw_temp, + .power_table = chtdc_ti_power_table, + .power_table_count = ARRAY_SIZE(chtdc_ti_power_table), + .thermal_table = chtdc_ti_thermal_table, + .thermal_table_count = ARRAY_SIZE(chtdc_ti_thermal_table), +}; + +static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); + int err; + + err = intel_pmic_install_opregion_handler(&pdev->dev, + ACPI_HANDLE(pdev->dev.parent), pmic->regmap, + &chtdc_ti_pmic_opregion_data); + if (err < 0) + return err; + + /* Re-enumerate devices depending on PMIC */ + acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent)); + return 0; +} + +static const struct platform_device_id chtdc_ti_pmic_opregion_id_table[] = { + { .name = "chtdc_ti_region" }, + {}, +}; + +static struct platform_driver chtdc_ti_pmic_opregion_driver = { + .probe = chtdc_ti_pmic_opregion_probe, + .driver = { + .name = "cht_dollar_cove_ti_pmic", + }, + .id_table = chtdc_ti_pmic_opregion_id_table, +}; +builtin_platform_driver(chtdc_ti_pmic_opregion_driver); diff --git a/drivers/acpi/pmic/intel_pmic_chtwc.c b/drivers/acpi/pmic/intel_pmic_chtwc.c index 85636d7a9d39..9912422c8185 100644 --- a/drivers/acpi/pmic/intel_pmic_chtwc.c +++ b/drivers/acpi/pmic/intel_pmic_chtwc.c @@ -260,11 +260,10 @@ static int intel_cht_wc_pmic_opregion_probe(struct platform_device *pdev) &intel_cht_wc_pmic_opregion_data); } -static struct platform_device_id cht_wc_opregion_id_table[] = { +static const struct platform_device_id cht_wc_opregion_id_table[] = { { .name = "cht_wcove_region" }, {}, }; -MODULE_DEVICE_TABLE(platform, cht_wc_opregion_id_table); static struct platform_driver intel_cht_wc_pmic_opregion_driver = { .probe = intel_cht_wc_pmic_opregion_probe, @@ -273,8 +272,4 @@ static struct platform_driver intel_cht_wc_pmic_opregion_driver = { }, .id_table = cht_wc_opregion_id_table, }; -module_platform_driver(intel_cht_wc_pmic_opregion_driver); - -MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC operation region driver"); -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(intel_cht_wc_pmic_opregion_driver); diff --git a/drivers/acpi/pmic/intel_pmic_crc.c b/drivers/acpi/pmic/intel_pmic_crc.c index d7f1761ab1bc..7ffa74048107 100644 --- a/drivers/acpi/pmic/intel_pmic_crc.c +++ b/drivers/acpi/pmic/intel_pmic_crc.c @@ -201,9 +201,4 @@ static struct platform_driver intel_crc_pmic_opregion_driver = { .name = "crystal_cove_pmic", }, }; - -static int __init intel_crc_pmic_opregion_driver_init(void) -{ - return platform_driver_register(&intel_crc_pmic_opregion_driver); -} -device_initcall(intel_crc_pmic_opregion_driver_init); +builtin_platform_driver(intel_crc_pmic_opregion_driver); diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c index 6c99d3f81095..316e55174aa9 100644 --- a/drivers/acpi/pmic/intel_pmic_xpower.c +++ b/drivers/acpi/pmic/intel_pmic_xpower.c @@ -278,9 +278,4 @@ static struct platform_driver intel_xpower_pmic_opregion_driver = { .name = "axp288_pmic_acpi", }, }; - -static int __init intel_xpower_pmic_opregion_driver_init(void) -{ - return platform_driver_register(&intel_xpower_pmic_opregion_driver); -} -device_initcall(intel_xpower_pmic_opregion_driver_init); +builtin_platform_driver(intel_xpower_pmic_opregion_driver); diff --git a/drivers/acpi/pmic/tps68470_pmic.c b/drivers/acpi/pmic/tps68470_pmic.c new file mode 100644 index 000000000000..7f3c567e8168 --- /dev/null +++ b/drivers/acpi/pmic/tps68470_pmic.c @@ -0,0 +1,455 @@ +/* + * TI TPS68470 PMIC operation region driver + * + * Copyright (C) 2017 Intel Corporation. All rights reserved. + * + * Author: Rajmohan Mani <rajmohan.mani@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 "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Based on drivers/acpi/pmic/intel_pmic* drivers + */ + +#include <linux/acpi.h> +#include <linux/mfd/tps68470.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +struct tps68470_pmic_table { + u32 address; /* operation region address */ + u32 reg; /* corresponding register */ + u32 bitmask; /* bit mask for power, clock */ +}; + +#define TI_PMIC_POWER_OPREGION_ID 0xB0 +#define TI_PMIC_VR_VAL_OPREGION_ID 0xB1 +#define TI_PMIC_CLOCK_OPREGION_ID 0xB2 +#define TI_PMIC_CLKFREQ_OPREGION_ID 0xB3 + +struct tps68470_pmic_opregion { + struct mutex lock; + struct regmap *regmap; +}; + +#define S_IO_I2C_EN (BIT(0) | BIT(1)) + +static const struct tps68470_pmic_table power_table[] = { + { + .address = 0x00, + .reg = TPS68470_REG_S_I2C_CTL, + .bitmask = S_IO_I2C_EN, + /* S_I2C_CTL */ + }, + { + .address = 0x04, + .reg = TPS68470_REG_VCMCTL, + .bitmask = BIT(0), + /* VCMCTL */ + }, + { + .address = 0x08, + .reg = TPS68470_REG_VAUX1CTL, + .bitmask = BIT(0), + /* VAUX1_CTL */ + }, + { + .address = 0x0C, + .reg = TPS68470_REG_VAUX2CTL, + .bitmask = BIT(0), + /* VAUX2CTL */ + }, + { + .address = 0x10, + .reg = TPS68470_REG_VACTL, + .bitmask = BIT(0), + /* VACTL */ + }, + { + .address = 0x14, + .reg = TPS68470_REG_VDCTL, + .bitmask = BIT(0), + /* VDCTL */ + }, +}; + +/* Table to set voltage regulator value */ +static const struct tps68470_pmic_table vr_val_table[] = { + { + .address = 0x00, + .reg = TPS68470_REG_VSIOVAL, + .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK, + /* TPS68470_REG_VSIOVAL */ + }, + { + .address = 0x04, + .reg = TPS68470_REG_VIOVAL, + .bitmask = TPS68470_VIOVAL_IOVOLT_MASK, + /* TPS68470_REG_VIOVAL */ + }, + { + .address = 0x08, + .reg = TPS68470_REG_VCMVAL, + .bitmask = TPS68470_VCMVAL_VCVOLT_MASK, + /* TPS68470_REG_VCMVAL */ + }, + { + .address = 0x0C, + .reg = TPS68470_REG_VAUX1VAL, + .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK, + /* TPS68470_REG_VAUX1VAL */ + }, + { + .address = 0x10, + .reg = TPS68470_REG_VAUX2VAL, + .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK, + /* TPS68470_REG_VAUX2VAL */ + }, + { + .address = 0x14, + .reg = TPS68470_REG_VAVAL, + .bitmask = TPS68470_VAVAL_AVOLT_MASK, + /* TPS68470_REG_VAVAL */ + }, + { + .address = 0x18, + .reg = TPS68470_REG_VDVAL, + .bitmask = TPS68470_VDVAL_DVOLT_MASK, + /* TPS68470_REG_VDVAL */ + }, +}; + +/* Table to configure clock frequency */ +static const struct tps68470_pmic_table clk_freq_table[] = { + { + .address = 0x00, + .reg = TPS68470_REG_POSTDIV2, + .bitmask = BIT(0) | BIT(1), + /* TPS68470_REG_POSTDIV2 */ + }, + { + .address = 0x04, + .reg = TPS68470_REG_BOOSTDIV, + .bitmask = 0x1F, + /* TPS68470_REG_BOOSTDIV */ + }, + { + .address = 0x08, + .reg = TPS68470_REG_BUCKDIV, + .bitmask = 0x0F, + /* TPS68470_REG_BUCKDIV */ + }, + { + .address = 0x0C, + .reg = TPS68470_REG_PLLSWR, + .bitmask = 0x13, + /* TPS68470_REG_PLLSWR */ + }, + { + .address = 0x10, + .reg = TPS68470_REG_XTALDIV, + .bitmask = 0xFF, + /* TPS68470_REG_XTALDIV */ + }, + { + .address = 0x14, + .reg = TPS68470_REG_PLLDIV, + .bitmask = 0xFF, + /* TPS68470_REG_PLLDIV */ + }, + { + .address = 0x18, + .reg = TPS68470_REG_POSTDIV, + .bitmask = 0x83, + /* TPS68470_REG_POSTDIV */ + }, +}; + +/* Table to configure and enable clocks */ +static const struct tps68470_pmic_table clk_table[] = { + { + .address = 0x00, + .reg = TPS68470_REG_PLLCTL, + .bitmask = 0xF5, + /* TPS68470_REG_PLLCTL */ + }, + { + .address = 0x04, + .reg = TPS68470_REG_PLLCTL2, + .bitmask = BIT(0), + /* TPS68470_REG_PLLCTL2 */ + }, + { + .address = 0x08, + .reg = TPS68470_REG_CLKCFG1, + .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | + TPS68470_CLKCFG1_MODE_B_MASK, + /* TPS68470_REG_CLKCFG1 */ + }, + { + .address = 0x0C, + .reg = TPS68470_REG_CLKCFG2, + .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | + TPS68470_CLKCFG1_MODE_B_MASK, + /* TPS68470_REG_CLKCFG2 */ + }, +}; + +static int pmic_get_reg_bit(u64 address, + const struct tps68470_pmic_table *table, + const unsigned int table_size, int *reg, + int *bitmask) +{ + u64 i; + + i = address / 4; + if (i >= table_size) + return -ENOENT; + + if (!reg || !bitmask) + return -EINVAL; + + *reg = table[i].reg; + *bitmask = table[i].bitmask; + + return 0; +} + +static int tps68470_pmic_get_power(struct regmap *regmap, int reg, + int bitmask, u64 *value) +{ + unsigned int data; + + if (regmap_read(regmap, reg, &data)) + return -EIO; + + *value = (data & bitmask) ? 1 : 0; + return 0; +} + +static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg, + int bitmask, u64 *value) +{ + unsigned int data; + + if (regmap_read(regmap, reg, &data)) + return -EIO; + + *value = data & bitmask; + return 0; +} + +static int tps68470_pmic_get_clk(struct regmap *regmap, int reg, + int bitmask, u64 *value) +{ + unsigned int data; + + if (regmap_read(regmap, reg, &data)) + return -EIO; + + *value = (data & bitmask) ? 1 : 0; + return 0; +} + +static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg, + int bitmask, u64 *value) +{ + unsigned int data; + + if (regmap_read(regmap, reg, &data)) + return -EIO; + + *value = data & bitmask; + return 0; +} + +static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg, + int bitmask, u64 value) +{ + return regmap_update_bits(regmap, reg, bitmask, value); +} + +static acpi_status tps68470_pmic_common_handler(u32 function, + acpi_physical_address address, + u32 bits, u64 *value, + void *region_context, + int (*get)(struct regmap *, + int, int, u64 *), + int (*update)(struct regmap *, + int, int, u64), + const struct tps68470_pmic_table *tbl, + unsigned int tbl_size) +{ + struct tps68470_pmic_opregion *opregion = region_context; + struct regmap *regmap = opregion->regmap; + int reg, ret, bitmask; + + if (bits != 32) + return AE_BAD_PARAMETER; + + ret = pmic_get_reg_bit(address, tbl, tbl_size, ®, &bitmask); + if (ret < 0) + return AE_BAD_PARAMETER; + + if (function == ACPI_WRITE && *value > bitmask) + return AE_BAD_PARAMETER; + + mutex_lock(&opregion->lock); + + ret = (function == ACPI_READ) ? + get(regmap, reg, bitmask, value) : + update(regmap, reg, bitmask, *value); + + mutex_unlock(&opregion->lock); + + return ret ? AE_ERROR : AE_OK; +} + +static acpi_status tps68470_pmic_cfreq_handler(u32 function, + acpi_physical_address address, + u32 bits, u64 *value, + void *handler_context, + void *region_context) +{ + return tps68470_pmic_common_handler(function, address, bits, value, + region_context, + tps68470_pmic_get_clk_freq, + ti_tps68470_regmap_update_bits, + clk_freq_table, + ARRAY_SIZE(clk_freq_table)); +} + +static acpi_status tps68470_pmic_clk_handler(u32 function, + acpi_physical_address address, u32 bits, + u64 *value, void *handler_context, + void *region_context) +{ + return tps68470_pmic_common_handler(function, address, bits, value, + region_context, + tps68470_pmic_get_clk, + ti_tps68470_regmap_update_bits, + clk_table, + ARRAY_SIZE(clk_table)); +} + +static acpi_status tps68470_pmic_vrval_handler(u32 function, + acpi_physical_address address, + u32 bits, u64 *value, + void *handler_context, + void *region_context) +{ + return tps68470_pmic_common_handler(function, address, bits, value, + region_context, + tps68470_pmic_get_vr_val, + ti_tps68470_regmap_update_bits, + vr_val_table, + ARRAY_SIZE(vr_val_table)); +} + +static acpi_status tps68470_pmic_pwr_handler(u32 function, + acpi_physical_address address, + u32 bits, u64 *value, + void *handler_context, + void *region_context) +{ + if (bits != 32) + return AE_BAD_PARAMETER; + + /* set/clear for bit 0, bits 0 and 1 together */ + if (function == ACPI_WRITE && + !(*value == 0 || *value == 1 || *value == 3)) { + return AE_BAD_PARAMETER; + } + + return tps68470_pmic_common_handler(function, address, bits, value, + region_context, + tps68470_pmic_get_power, + ti_tps68470_regmap_update_bits, + power_table, + ARRAY_SIZE(power_table)); +} + +static int tps68470_pmic_opregion_probe(struct platform_device *pdev) +{ + struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent); + acpi_handle handle = ACPI_HANDLE(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct tps68470_pmic_opregion *opregion; + acpi_status status; + + if (!dev || !tps68470_regmap) { + dev_warn(dev, "dev or regmap is NULL\n"); + return -EINVAL; + } + + if (!handle) { + dev_warn(dev, "acpi handle is NULL\n"); + return -ENODEV; + } + + opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL); + if (!opregion) + return -ENOMEM; + + mutex_init(&opregion->lock); + opregion->regmap = tps68470_regmap; + + status = acpi_install_address_space_handler(handle, + TI_PMIC_POWER_OPREGION_ID, + tps68470_pmic_pwr_handler, + NULL, opregion); + if (ACPI_FAILURE(status)) + goto out_mutex_destroy; + + status = acpi_install_address_space_handler(handle, + TI_PMIC_VR_VAL_OPREGION_ID, + tps68470_pmic_vrval_handler, + NULL, opregion); + if (ACPI_FAILURE(status)) + goto out_remove_power_handler; + + status = acpi_install_address_space_handler(handle, + TI_PMIC_CLOCK_OPREGION_ID, + tps68470_pmic_clk_handler, + NULL, opregion); + if (ACPI_FAILURE(status)) + goto out_remove_vr_val_handler; + + status = acpi_install_address_space_handler(handle, + TI_PMIC_CLKFREQ_OPREGION_ID, + tps68470_pmic_cfreq_handler, + NULL, opregion); + if (ACPI_FAILURE(status)) + goto out_remove_clk_handler; + + return 0; + +out_remove_clk_handler: + acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID, + tps68470_pmic_clk_handler); +out_remove_vr_val_handler: + acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID, + tps68470_pmic_vrval_handler); +out_remove_power_handler: + acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID, + tps68470_pmic_pwr_handler); +out_mutex_destroy: + mutex_destroy(&opregion->lock); + return -ENODEV; +} + +static struct platform_driver tps68470_pmic_opregion_driver = { + .probe = tps68470_pmic_opregion_probe, + .driver = { + .name = "tps68470_pmic_opregion", + }, +}; + +builtin_platform_driver(tps68470_pmic_opregion_driver) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d50a7b6ccddd..abb559cd28d7 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -207,6 +207,7 @@ static void tsc_check_state(int state) switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: case X86_VENDOR_INTEL: + case X86_VENDOR_CENTAUR: /* * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. @@ -291,6 +292,9 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; pr->power.states[ACPI_STATE_C1].valid = 1; pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT; + + snprintf(pr->power.states[ACPI_STATE_C1].desc, + ACPI_CX_DESC_LEN, "ACPI HLT"); } /* the C0 state only exists as a filler in our array */ pr->power.states[ACPI_STATE_C0].valid = 1; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 18b72eec3507..c7cf48ad5cb9 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -159,7 +159,7 @@ void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) { int ret; - if (ignore_ppc) { + if (ignore_ppc || !pr->performance) { /* * Only when it is notification event, the _OST object * will be evaluated. Otherwise it is skipped. diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index e26ea209b63e..5815356ea6ad 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1271,9 +1271,17 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, return 0; } +static const void * +acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, + const struct device *dev) +{ + return acpi_device_get_match_data(dev); +} + #define DECLARE_ACPI_FWNODE_OPS(ops) \ const struct fwnode_operations ops = { \ .device_is_available = acpi_fwnode_device_is_available, \ + .device_get_match_data = acpi_fwnode_device_get_match_data, \ .property_present = acpi_fwnode_property_present, \ .property_read_int_array = \ acpi_fwnode_property_read_int_array, \ diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index d85e010ee2cc..316a0fc785e3 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -381,6 +381,7 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity) case ACPI_ACTIVE_BOTH: if (triggering == ACPI_EDGE_SENSITIVE) return IRQ_TYPE_EDGE_BOTH; + /* fall through */ default: return IRQ_TYPE_NONE; } diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 2fa8304171e0..7a3431018e0a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -275,8 +275,8 @@ static int acpi_smbus_hc_add(struct acpi_device *device) device->driver_data = hc; acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc); - printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n", - hc->ec, hc->offset, hc->query_bit); + dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n", + hc->offset, hc->query_bit); return 0; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 602f8ff212f2..8e63d937babb 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1024,6 +1024,9 @@ static void acpi_device_get_busid(struct acpi_device *device) case ACPI_BUS_TYPE_SLEEP_BUTTON: strcpy(device->pnp.bus_id, "SLPF"); break; + case ACPI_BUS_TYPE_ECDT_EC: + strcpy(device->pnp.bus_id, "ECDT"); + break; default: acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); /* Clean up trailing underscores (if any) */ @@ -1304,6 +1307,9 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, case ACPI_BUS_TYPE_SLEEP_BUTTON: acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF); break; + case ACPI_BUS_TYPE_ECDT_EC: + acpi_add_id(pnp, ACPI_ECDT_HID); + break; } } @@ -1505,41 +1511,38 @@ static void acpi_init_coherency(struct acpi_device *adev) adev->flags.coherent_dma = cca; } -static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) +static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data) { - bool *is_spi_i2c_slave_p = data; + bool *is_serial_bus_slave_p = data; if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) return 1; - /* - * devices that are connected to UART still need to be enumerated to - * platform bus - */ - if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) - *is_spi_i2c_slave_p = true; + *is_serial_bus_slave_p = true; /* no need to do more checking */ return -1; } -static bool acpi_is_spi_i2c_slave(struct acpi_device *device) +static bool acpi_is_serial_bus_slave(struct acpi_device *device) { struct list_head resource_list; - bool is_spi_i2c_slave = false; + bool is_serial_bus_slave = false; /* Macs use device properties in lieu of _CRS resources */ if (x86_apple_machine && (fwnode_property_present(&device->fwnode, "spiSclkPeriod") || - fwnode_property_present(&device->fwnode, "i2cAddress"))) + fwnode_property_present(&device->fwnode, "i2cAddress") || + fwnode_property_present(&device->fwnode, "baud"))) return true; INIT_LIST_HEAD(&resource_list); - acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, - &is_spi_i2c_slave); + acpi_dev_get_resources(device, &resource_list, + acpi_check_serial_bus_slave, + &is_serial_bus_slave); acpi_dev_free_resource_list(&resource_list); - return is_spi_i2c_slave; + return is_serial_bus_slave; } void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, @@ -1557,11 +1560,13 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, acpi_bus_get_flags(device); device->flags.match_driver = false; device->flags.initialized = true; - device->flags.spi_i2c_slave = acpi_is_spi_i2c_slave(device); + device->flags.serial_bus_slave = acpi_is_serial_bus_slave(device); acpi_device_clear_enumerated(device); device_initialize(&device->dev); dev_set_uevent_suppress(&device->dev, true); acpi_init_coherency(device); + /* Assume there are unmet deps until acpi_device_dep_initialize() runs */ + device->dep_unmet = 1; } void acpi_device_add_finalize(struct acpi_device *device) @@ -1585,6 +1590,14 @@ static int acpi_add_single_object(struct acpi_device **child, } acpi_init_device_object(device, handle, type, sta); + /* + * For ACPI_BUS_TYPE_DEVICE getting the status is delayed till here so + * that we can call acpi_bus_get_status() and use its quirk handling. + * Note this must be done before the get power-/wakeup_dev-flags calls. + */ + if (type == ACPI_BUS_TYPE_DEVICE) + acpi_bus_get_status(device); + acpi_bus_get_power_flags(device); acpi_bus_get_wakeup_device_flags(device); @@ -1657,9 +1670,11 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, return -ENODEV; *type = ACPI_BUS_TYPE_DEVICE; - status = acpi_bus_get_status_handle(handle, sta); - if (ACPI_FAILURE(status)) - *sta = 0; + /* + * acpi_add_single_object updates this once we've an acpi_device + * so that acpi_bus_get_status' quirk handling can be used. + */ + *sta = 0; break; case ACPI_TYPE_PROCESSOR: *type = ACPI_BUS_TYPE_PROCESSOR; @@ -1757,6 +1772,8 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) acpi_status status; int i; + adev->dep_unmet = 0; + if (!acpi_has_method(adev->handle, "_DEP")) return; @@ -1841,10 +1858,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, static void acpi_default_enumeration(struct acpi_device *device) { /* - * Do not enumerate SPI/I2C slaves as they will be enumerated by their - * respective parents. + * Do not enumerate SPI/I2C/UART slaves as they will be enumerated by + * their respective parents. */ - if (!device->flags.spi_i2c_slave) { + if (!device->flags.serial_bus_slave) { acpi_create_platform_device(device, NULL); acpi_device_set_enumerated(device); } else { @@ -1941,7 +1958,7 @@ static void acpi_bus_attach(struct acpi_device *device) return; device->flags.match_driver = true; - if (ret > 0 && !device->flags.spi_i2c_slave) { + if (ret > 0 && !device->flags.serial_bus_slave) { acpi_device_set_enumerated(device); goto ok; } @@ -1950,7 +1967,7 @@ static void acpi_bus_attach(struct acpi_device *device) if (ret < 0) return; - if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave) + if (!device->pnp.type.platform_id && !device->flags.serial_bus_slave) acpi_device_set_enumerated(device); else acpi_default_enumeration(device); @@ -2049,6 +2066,21 @@ void acpi_bus_trim(struct acpi_device *adev) } EXPORT_SYMBOL_GPL(acpi_bus_trim); +int acpi_bus_register_early_device(int type) +{ + struct acpi_device *device = NULL; + int result; + + result = acpi_add_single_object(&device, NULL, + type, ACPI_STA_DEFAULT); + if (result) + return result; + + device->flags.match_driver = true; + return device_attach(&device->dev); +} +EXPORT_SYMBOL_GPL(acpi_bus_register_early_device); + static int acpi_bus_scan_fixed(void) { int result = 0; @@ -2122,6 +2154,7 @@ int __init acpi_scan_init(void) acpi_int340x_thermal_init(); acpi_amba_init(); acpi_watchdog_init(); + acpi_init_lpit(); acpi_scan_add_handler(&generic_device_handler); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 6804ddab3052..46cde0912762 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -160,6 +160,14 @@ static int __init init_nvs_nosave(const struct dmi_system_id *d) return 0; } +static bool acpi_sleep_no_lps0; + +static int __init init_no_lps0(const struct dmi_system_id *d) +{ + acpi_sleep_no_lps0 = true; + return 0; +} + static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { { .callback = init_old_suspend_ordering, @@ -343,13 +351,36 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), }, }, + /* + * https://bugzilla.kernel.org/show_bug.cgi?id=196907 + * Some Dell XPS13 9360 cannot do suspend-to-idle using the Low Power + * S0 Idle firmware interface. + */ + { + .callback = init_no_lps0, + .ident = "Dell XPS13 9360", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), + }, + }, {}, }; +static bool ignore_blacklist; + +void __init acpi_sleep_no_blacklist(void) +{ + ignore_blacklist = true; +} + static void __init acpi_sleep_dmi_check(void) { int year; + if (ignore_blacklist) + return; + if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) acpi_nvs_nosave_s3(); @@ -485,6 +516,7 @@ static void acpi_pm_end(void) } #else /* !CONFIG_ACPI_SLEEP */ #define acpi_target_sleep_state ACPI_STATE_S0 +#define acpi_sleep_no_lps0 (false) static inline void acpi_sleep_dmi_check(void) {} #endif /* CONFIG_ACPI_SLEEP */ @@ -675,7 +707,8 @@ static const struct acpi_device_id lps0_device_ids[] = { #define ACPI_LPS0_ENTRY 5 #define ACPI_LPS0_EXIT 6 -#define ACPI_S2IDLE_FUNC_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) +#define ACPI_LPS0_SCREEN_MASK ((1 << ACPI_LPS0_SCREEN_OFF) | (1 << ACPI_LPS0_SCREEN_ON)) +#define ACPI_LPS0_PLATFORM_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) static acpi_handle lps0_device_handle; static guid_t lps0_dsm_guid; @@ -863,6 +896,12 @@ static int lps0_device_attach(struct acpi_device *adev, if (lps0_device_handle) return 0; + if (acpi_sleep_no_lps0) { + acpi_handle_info(adev->handle, + "Low Power S0 Idle interface disabled\n"); + return 0; + } + if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) return 0; @@ -872,7 +911,8 @@ static int lps0_device_attach(struct acpi_device *adev, if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { char bitmask = *(char *)out_obj->buffer.pointer; - if ((bitmask & ACPI_S2IDLE_FUNC_MASK) == ACPI_S2IDLE_FUNC_MASK) { + if ((bitmask & ACPI_LPS0_PLATFORM_MASK) == ACPI_LPS0_PLATFORM_MASK || + (bitmask & ACPI_LPS0_SCREEN_MASK) == ACPI_LPS0_SCREEN_MASK) { lps0_dsm_func_mask = bitmask; lps0_device_handle = adev->handle; /* diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index 324b35bfe781..9d52743080a4 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -21,7 +21,7 @@ * occasionally getting stuck as 1. To avoid the potential for a hang, check * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART * implementations, so only do so if an affected platform is detected in - * parse_spcr(). + * acpi_parse_spcr(). */ bool qdf2400_e44_present; EXPORT_SYMBOL(qdf2400_e44_present); @@ -74,19 +74,21 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb) } /** - * parse_spcr() - parse ACPI SPCR table and add preferred console + * acpi_parse_spcr() - parse ACPI SPCR table and add preferred console * - * @earlycon: set up earlycon for the console specified by the table + * @enable_earlycon: set up earlycon for the console specified by the table + * @enable_console: setup the console specified by the table. * * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be * defined to parse ACPI SPCR table. As a result of the parsing preferred - * console is registered and if @earlycon is true, earlycon is set up. + * console is registered and if @enable_earlycon is true, earlycon is set up. + * If @enable_console is true the system console is also configured. * * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called * from arch initialization code as soon as the DT/ACPI decision is made. * */ -int __init parse_spcr(bool earlycon) +int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console) { static char opts[64]; struct acpi_table_spcr *table; @@ -105,17 +107,15 @@ int __init parse_spcr(bool earlycon) if (ACPI_FAILURE(status)) return -ENOENT; - if (table->header.revision < 2) { - err = -ENOENT; - pr_err("wrong table version\n"); - goto done; - } + if (table->header.revision < 2) + pr_info("SPCR table version %d\n", table->header.revision); if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { switch (ACPI_ACCESS_BIT_WIDTH(( table->serial_port.access_width))) { default: pr_err("Unexpected SPCR Access Width. Defaulting to byte size\n"); + /* fall through */ case 8: iotype = "mmio"; break; @@ -185,7 +185,7 @@ int __init parse_spcr(bool earlycon) */ if (qdf2400_erratum_44_present(&table->header)) { qdf2400_e44_present = true; - if (earlycon) + if (enable_earlycon) uart = "qdf2400_e44"; } @@ -205,11 +205,13 @@ int __init parse_spcr(bool earlycon) pr_info("console: %s\n", opts); - if (earlycon) + if (enable_earlycon) setup_earlycon(opts); - err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); - + if (enable_console) + err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); + else + err = 0; done: acpi_put_table((struct acpi_table_header *)table); return err; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 0fd57bf33524..4fc59c3bc673 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -169,7 +169,8 @@ module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); static char trace_method_name[1024]; -int param_set_trace_method_name(const char *val, const struct kernel_param *kp) +static int param_set_trace_method_name(const char *val, + const struct kernel_param *kp) { u32 saved_flags = 0; bool is_abs_path = true; @@ -230,7 +231,8 @@ module_param_cb(trace_method_name, ¶m_ops_trace_method, &trace_method_name, module_param_cb(trace_debug_layer, ¶m_ops_trace_attrib, &acpi_gbl_trace_dbg_layer, 0644); module_param_cb(trace_debug_level, ¶m_ops_trace_attrib, &acpi_gbl_trace_dbg_level, 0644); -static int param_set_trace_state(const char *val, struct kernel_param *kp) +static int param_set_trace_state(const char *val, + const struct kernel_param *kp) { acpi_status status; const char *method = trace_method_name; @@ -266,7 +268,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) return 0; } -static int param_get_trace_state(char *buffer, struct kernel_param *kp) +static int param_get_trace_state(char *buffer, const struct kernel_param *kp) { if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) return sprintf(buffer, "disable"); @@ -295,7 +297,8 @@ MODULE_PARM_DESC(aml_debug_output, "To enable/disable the ACPI Debug Object output."); /* /sys/module/acpi/parameters/acpica_version */ -static int param_get_acpica_version(char *buffer, struct kernel_param *kp) +static int param_get_acpica_version(char *buffer, + const struct kernel_param *kp) { int result; @@ -813,14 +816,8 @@ end: * interface: * echo unmask > /sys/firmware/acpi/interrupts/gpe00 */ - -/* - * Currently, the GPE flooding prevention only supports to mask the GPEs - * numbered from 00 to 7f. - */ -#define ACPI_MASKABLE_GPE_MAX 0x80 - -static u64 __initdata acpi_masked_gpes; +#define ACPI_MASKABLE_GPE_MAX 0xFF +static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata; static int __init acpi_gpe_set_masked_gpes(char *val) { @@ -828,7 +825,7 @@ static int __init acpi_gpe_set_masked_gpes(char *val) if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) return -EINVAL; - acpi_masked_gpes |= ((u64)1<<gpe); + set_bit(gpe, acpi_masked_gpes_map); return 1; } @@ -840,15 +837,11 @@ void __init acpi_gpe_apply_masked_gpes(void) acpi_status status; u8 gpe; - for (gpe = 0; - gpe < min_t(u8, ACPI_MASKABLE_GPE_MAX, acpi_current_gpe_count); - gpe++) { - if (acpi_masked_gpes & ((u64)1<<gpe)) { - status = acpi_get_gpe_device(gpe, &handle); - if (ACPI_SUCCESS(status)) { - pr_info("Masking GPE 0x%x.\n", gpe); - (void)acpi_mask_gpe(handle, gpe, TRUE); - } + for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) { + status = acpi_get_gpe_device(gpe, &handle); + if (ACPI_SUCCESS(status)) { + pr_info("Masking GPE 0x%x.\n", gpe); + (void)acpi_mask_gpe(handle, gpe, TRUE); } } } diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 80ce2a7d224b..7bcb66ccccf3 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -456,7 +456,8 @@ static const char * const table_sigs[] = { 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, NULL }; + ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_IORT, + NULL }; #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 0a9e5979aaa9..78db97687f26 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -355,6 +355,7 @@ acpi_evaluate_reference(acpi_handle handle, } if (package->package.count > ACPI_MAX_HANDLES) { + kfree(package); return AE_NO_MEMORY; } list->count = package->package.count; @@ -736,16 +737,17 @@ bool acpi_dev_found(const char *hid) } EXPORT_SYMBOL(acpi_dev_found); -struct acpi_dev_present_info { +struct acpi_dev_match_info { + const char *dev_name; struct acpi_device_id hid[2]; const char *uid; s64 hrv; }; -static int acpi_dev_present_cb(struct device *dev, void *data) +static int acpi_dev_match_cb(struct device *dev, void *data) { struct acpi_device *adev = to_acpi_device(dev); - struct acpi_dev_present_info *match = data; + struct acpi_dev_match_info *match = data; unsigned long long hrv; acpi_status status; @@ -756,6 +758,8 @@ static int acpi_dev_present_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; @@ -788,20 +792,44 @@ static int acpi_dev_present_cb(struct device *dev, void *data) */ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) { - struct acpi_dev_present_info match = {}; + struct acpi_dev_match_info match = {}; struct device *dev; strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); match.uid = uid; match.hrv = hrv; - dev = bus_find_device(&acpi_bus_type, NULL, &match, - acpi_dev_present_cb); - + dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); return !!dev; } EXPORT_SYMBOL(acpi_dev_present); +/** + * acpi_dev_get_first_match_name - Return name of 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 + * at the moment of invocation, or NULL otherwise. + * + * 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_dev_match_info match = {}; + struct device *dev; + + strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); + match.uid = uid; + match.hrv = hrv; + + dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); + return dev ? match.dev_name : NULL; +} +EXPORT_SYMBOL(acpi_dev_get_first_match_name); + /* * acpi_backlight= handling, this is done here rather then in video_detect.c * because __setup cannot be used in modules. diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index b4fbb9929482..ec5b0f190231 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -71,18 +71,34 @@ static const struct always_present_id always_present_ids[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), }), /* - * The GPD win BIOS dated 20170320 has disabled the accelerometer, the + * The GPD win BIOS dated 20170221 has disabled the accelerometer, the * drivers sometimes cause crashes under Windows and this is how the * manufacturer has solved this :| Note that the the DMI data is less * generic then it seems, a board_vendor of "AMI Corporation" is quite * rare and a board_name of "Default String" also is rare. + * + * Unfortunately the GPD pocket also uses these strings and its BIOS + * was copy-pasted from the GPD win, so it has a disabled KIOX000A + * node which we should not enable, thus we also check the BIOS date. */ ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), DMI_MATCH(DMI_BOARD_NAME, "Default string"), DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), + DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") + }), + ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Default string"), + DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") }), + ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Default string"), + DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), + DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") + }), }; bool acpi_device_always_present(struct acpi_device *adev) |