diff options
Diffstat (limited to 'drivers/acpi')
39 files changed, 889 insertions, 420 deletions
| diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index dd1eea90f67f..9705fc986da9 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -138,7 +138,6 @@ config ACPI_REV_OVERRIDE_POSSIBLE  config ACPI_EC_DEBUGFS  	tristate "EC read/write access through /sys/kernel/debug/ec" -	default n  	help  	  Say N to disable Embedded Controller /sys/kernel/debug interface @@ -283,7 +282,6 @@ config ACPI_PROCESSOR  config ACPI_IPMI  	tristate "IPMI"  	depends on IPMI_HANDLER -	default n  	help  	  This driver enables the ACPI to access the BMC controller. And it  	  uses the IPMI request/response message to communicate with BMC @@ -361,7 +359,6 @@ config ACPI_TABLE_UPGRADE  config ACPI_DEBUG  	bool "Debug Statements" -	default n  	help  	  The ACPI subsystem can produce debug output.  Saying Y enables this  	  output and increases the kernel size by around 50K. @@ -374,7 +371,6 @@ config ACPI_DEBUG  config ACPI_PCI_SLOT  	bool "PCI slot detection driver"  	depends on SYSFS -	default n  	help  	  This driver creates entries in /sys/bus/pci/slots/ for all PCI  	  slots in the system.  This can help correlate PCI bus addresses, @@ -436,7 +432,6 @@ config ACPI_HED  config ACPI_CUSTOM_METHOD  	tristate "Allow ACPI methods to be inserted/replaced at run time"  	depends on DEBUG_FS -	default n  	help  	  This debug facility allows ACPI AML methods to be inserted and/or  	  replaced without rebooting the system. For details refer to: @@ -481,7 +476,6 @@ config ACPI_EXTLOG  	tristate "Extended Error Log support"  	depends on X86_MCE && X86_LOCAL_APIC && EDAC  	select UEFI_CPER -	default n  	help  	  Certain usages such as Predictive Failure Analysis (PFA) require  	  more information about the error than what can be described in diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index 1b64419e2fec..712fd31674a6 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -46,7 +46,7 @@ struct acpi_ipmi_device {  	spinlock_t tx_msg_lock;  	acpi_handle handle;  	struct device *dev; -	ipmi_user_t user_interface; +	struct ipmi_user *user_interface;  	int ipmi_ifnum; /* IPMI interface number */  	long curr_msgid;  	bool dead; @@ -125,7 +125,7 @@ ipmi_dev_alloc(int iface, struct device *dev, acpi_handle handle)  {  	struct acpi_ipmi_device *ipmi_device;  	int err; -	ipmi_user_t user; +	struct ipmi_user *user;  	ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL);  	if (!ipmi_device) diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c index cf4fc0161164..e43cb71b6972 100644 --- a/drivers/acpi/acpi_lpit.c +++ b/drivers/acpi/acpi_lpit.c @@ -117,11 +117,17 @@ static void lpit_update_residency(struct lpit_residency_info *info,  		if (!info->iomem_addr)  			return; +		if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) +			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) { +		if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) +			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_cpu_residency_us.attr, diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index bf64cfa30feb..b9bda06d344d 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -16,6 +16,7 @@  #include <linux/err.h>  #include <linux/io.h>  #include <linux/mutex.h> +#include <linux/pci.h>  #include <linux/platform_device.h>  #include <linux/platform_data/clk-lpss.h>  #include <linux/platform_data/x86/pmc_atom.h> @@ -83,6 +84,7 @@ struct lpss_device_desc {  	size_t prv_size_override;  	struct property_entry *properties;  	void (*setup)(struct lpss_private_data *pdata); +	bool resume_from_noirq;  };  static const struct lpss_device_desc lpss_dma_desc = { @@ -99,6 +101,9 @@ struct lpss_private_data {  	u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];  }; +/* Devices which need to be in D3 before lpss_iosf_enter_d3_state() proceeds */ +static u32 pmc_atom_d3_mask = 0xfe000ffe; +  /* LPSS run time quirks */  static unsigned int lpss_quirks; @@ -175,6 +180,21 @@ static void byt_pwm_setup(struct lpss_private_data *pdata)  static void byt_i2c_setup(struct lpss_private_data *pdata)  { +	const char *uid_str = acpi_device_uid(pdata->adev); +	acpi_handle handle = pdata->adev->handle; +	unsigned long long shared_host = 0; +	acpi_status status; +	long uid = 0; + +	/* Expected to always be true, but better safe then sorry */ +	if (uid_str) +		uid = simple_strtol(uid_str, NULL, 10); + +	/* Detect I2C bus shared with PUNIT and ignore its d3 status */ +	status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host); +	if (ACPI_SUCCESS(status) && shared_host && uid) +		pmc_atom_d3_mask &= ~(BIT_LPSS2_F1_I2C1 << (uid - 1)); +  	lpss_deassert_reset(pdata);  	if (readl(pdata->mmio_base + pdata->dev_desc->prv_offset)) @@ -274,12 +294,14 @@ static const struct lpss_device_desc byt_i2c_dev_desc = {  	.flags = LPSS_CLK | LPSS_SAVE_CTX,  	.prv_offset = 0x800,  	.setup = byt_i2c_setup, +	.resume_from_noirq = true,  };  static const struct lpss_device_desc bsw_i2c_dev_desc = {  	.flags = LPSS_CLK | LPSS_SAVE_CTX | LPSS_NO_D3_DELAY,  	.prv_offset = 0x800,  	.setup = byt_i2c_setup, +	.resume_from_noirq = true,  };  static const struct lpss_device_desc bsw_spi_dev_desc = { @@ -292,7 +314,7 @@ static const struct lpss_device_desc bsw_spi_dev_desc = {  #define ICPU(model)	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }  static const struct x86_cpu_id lpss_cpu_ids[] = { -	ICPU(INTEL_FAM6_ATOM_SILVERMONT1),	/* Valleyview, Bay Trail */ +	ICPU(INTEL_FAM6_ATOM_SILVERMONT),	/* Valleyview, Bay Trail */  	ICPU(INTEL_FAM6_ATOM_AIRMONT),	/* Braswell, Cherry Trail */  	{}  }; @@ -327,9 +349,11 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {  	{ "INT33FC", },  	/* Braswell LPSS devices */ +	{ "80862286", LPSS_ADDR(lpss_dma_desc) },  	{ "80862288", LPSS_ADDR(bsw_pwm_dev_desc) },  	{ "8086228A", LPSS_ADDR(bsw_uart_dev_desc) },  	{ "8086228E", LPSS_ADDR(bsw_spi_dev_desc) }, +	{ "808622C0", LPSS_ADDR(lpss_dma_desc) },  	{ "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) },  	/* Broadwell LPSS devices */ @@ -451,26 +475,35 @@ struct lpss_device_links {   */  static const struct lpss_device_links lpss_device_links[] = {  	{"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME}, +	{"808622C1", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, +	{"80860F41", "5", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME},  }; -static bool hid_uid_match(const char *hid1, const char *uid1, +static bool hid_uid_match(struct acpi_device *adev,  			  const char *hid2, const char *uid2)  { -	return !strcmp(hid1, hid2) && uid1 && uid2 && !strcmp(uid1, uid2); +	const char *hid1 = acpi_device_hid(adev); +	const char *uid1 = acpi_device_uid(adev); + +	if (strcmp(hid1, hid2)) +		return false; + +	if (!uid2) +		return true; + +	return uid1 && !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); +	return hid_uid_match(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); +	return hid_uid_match(adev, link->consumer_hid, link->consumer_uid);  }  struct hid_uid { @@ -486,18 +519,23 @@ static int match_hid_uid(struct device *dev, void *data)  	if (!adev)  		return 0; -	return hid_uid_match(acpi_device_hid(adev), acpi_device_uid(adev), -			     id->hid, id->uid); +	return hid_uid_match(adev, id->hid, id->uid);  }  static struct device *acpi_lpss_find_device(const char *hid, const char *uid)  { +	struct device *dev; +  	struct hid_uid data = {  		.hid = hid,  		.uid = uid,  	}; -	return bus_find_device(&platform_bus_type, NULL, &data, match_hid_uid); +	dev = bus_find_device(&platform_bus_type, NULL, &data, match_hid_uid); +	if (dev) +		return dev; + +	return bus_find_device(&pci_bus_type, NULL, &data, match_hid_uid);  }  static bool acpi_lpss_dep(struct acpi_device *adev, acpi_handle handle) @@ -892,7 +930,7 @@ static void lpss_iosf_enter_d3_state(void)  	 * Here we read the values related to LPSS power island, i.e. LPSS  	 * devices, excluding both LPSS DMA controllers, along with SCC domain.  	 */ -	u32 func_dis, d3_sts_0, pmc_status, pmc_mask = 0xfe000ffe; +	u32 func_dis, d3_sts_0, pmc_status;  	int ret;  	ret = pmc_atom_read(PMC_FUNC_DIS, &func_dis); @@ -910,7 +948,7 @@ static void lpss_iosf_enter_d3_state(void)  	 * Shutdown both LPSS DMA controllers if and only if all other devices  	 * are already in D3hot.  	 */ -	pmc_status = (~(d3_sts_0 | func_dis)) & pmc_mask; +	pmc_status = (~(d3_sts_0 | func_dis)) & pmc_atom_d3_mask;  	if (pmc_status)  		goto exit; @@ -1004,7 +1042,7 @@ static int acpi_lpss_resume(struct device *dev)  }  #ifdef CONFIG_PM_SLEEP -static int acpi_lpss_suspend_late(struct device *dev) +static int acpi_lpss_do_suspend_late(struct device *dev)  {  	int ret; @@ -1015,12 +1053,62 @@ static int acpi_lpss_suspend_late(struct device *dev)  	return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev));  } -static int acpi_lpss_resume_early(struct device *dev) +static int acpi_lpss_suspend_late(struct device *dev) +{ +	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + +	if (pdata->dev_desc->resume_from_noirq) +		return 0; + +	return acpi_lpss_do_suspend_late(dev); +} + +static int acpi_lpss_suspend_noirq(struct device *dev) +{ +	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); +	int ret; + +	if (pdata->dev_desc->resume_from_noirq) { +		ret = acpi_lpss_do_suspend_late(dev); +		if (ret) +			return ret; +	} + +	return acpi_subsys_suspend_noirq(dev); +} + +static int acpi_lpss_do_resume_early(struct device *dev)  {  	int ret = acpi_lpss_resume(dev);  	return ret ? ret : pm_generic_resume_early(dev);  } + +static int acpi_lpss_resume_early(struct device *dev) +{ +	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + +	if (pdata->dev_desc->resume_from_noirq) +		return 0; + +	return acpi_lpss_do_resume_early(dev); +} + +static int acpi_lpss_resume_noirq(struct device *dev) +{ +	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); +	int ret; + +	ret = acpi_subsys_resume_noirq(dev); +	if (ret) +		return ret; + +	if (!dev_pm_may_skip_resume(dev) && pdata->dev_desc->resume_from_noirq) +		ret = acpi_lpss_do_resume_early(dev); + +	return ret; +} +  #endif /* CONFIG_PM_SLEEP */  static int acpi_lpss_runtime_suspend(struct device *dev) @@ -1050,8 +1138,8 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {  		.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, +		.suspend_noirq = acpi_lpss_suspend_noirq, +		.resume_noirq = acpi_lpss_resume_noirq,  		.resume_early = acpi_lpss_resume_early,  		.freeze = acpi_subsys_freeze,  		.freeze_late = acpi_subsys_freeze_late, diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 552c1f725b6c..a47676a55b84 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -70,6 +70,7 @@ static void power_saving_mwait_init(void)  #if defined(CONFIG_X86)  	switch (boot_cpu_data.x86_vendor) { +	case X86_VENDOR_HYGON:  	case X86_VENDOR_AMD:  	case X86_VENDOR_INTEL:  		/* diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 449d86d39965..fc447410ae4d 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -643,7 +643,7 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,  	status = acpi_get_type(handle, &acpi_type);  	if (ACPI_FAILURE(status)) -		return false; +		return status;  	switch (acpi_type) {  	case ACPI_TYPE_PROCESSOR: @@ -663,11 +663,12 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,  	}  	processor_validated_ids_update(uid); -	return true; +	return AE_OK;  err: +	/* Exit on error, but don't abort the namespace walk */  	acpi_handle_info(handle, "Invalid processor object\n"); -	return false; +	return AE_OK;  } diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c index e99c4ed7e677..33a4bcdaa4d7 100644 --- a/drivers/acpi/acpi_tad.c +++ b/drivers/acpi/acpi_tad.c @@ -52,6 +52,201 @@ struct acpi_tad_driver_data {  	u32 capabilities;  }; +struct acpi_tad_rt { +	u16 year;  /* 1900 - 9999 */ +	u8 month;  /* 1 - 12 */ +	u8 day;    /* 1 - 31 */ +	u8 hour;   /* 0 - 23 */ +	u8 minute; /* 0 - 59 */ +	u8 second; /* 0 - 59 */ +	u8 valid;  /* 0 (failed) or 1 (success) for reads, 0 for writes */ +	u16 msec;  /* 1 - 1000 */ +	s16 tz;    /* -1440 to 1440 or 2047 (unspecified) */ +	u8 daylight; +	u8 padding[3]; /* must be 0 */ +} __packed; + +static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt) +{ +	acpi_handle handle = ACPI_HANDLE(dev); +	union acpi_object args[] = { +		{ .type = ACPI_TYPE_BUFFER, }, +	}; +	struct acpi_object_list arg_list = { +		.pointer = args, +		.count = ARRAY_SIZE(args), +	}; +	unsigned long long retval; +	acpi_status status; + +	if (rt->year < 1900 || rt->year > 9999 || +	    rt->month < 1 || rt->month > 12 || +	    rt->hour > 23 || rt->minute > 59 || rt->second > 59 || +	    rt->tz < -1440 || (rt->tz > 1440 && rt->tz != 2047) || +	    rt->daylight > 3) +		return -ERANGE; + +	args[0].buffer.pointer = (u8 *)rt; +	args[0].buffer.length = sizeof(*rt); + +	pm_runtime_get_sync(dev); + +	status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval); + +	pm_runtime_put_sync(dev); + +	if (ACPI_FAILURE(status) || retval) +		return -EIO; + +	return 0; +} + +static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt) +{ +	acpi_handle handle = ACPI_HANDLE(dev); +	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER }; +	union acpi_object *out_obj; +	struct acpi_tad_rt *data; +	acpi_status status; +	int ret = -EIO; + +	pm_runtime_get_sync(dev); + +	status = acpi_evaluate_object(handle, "_GRT", NULL, &output); + +	pm_runtime_put_sync(dev); + +	if (ACPI_FAILURE(status)) +		goto out_free; + +	out_obj = output.pointer; +	if (out_obj->type != ACPI_TYPE_BUFFER) +		goto out_free; + +	if (out_obj->buffer.length != sizeof(*rt)) +		goto out_free; + +	data = (struct acpi_tad_rt *)(out_obj->buffer.pointer); +	if (!data->valid) +		goto out_free; + +	memcpy(rt, data, sizeof(*rt)); +	ret = 0; + +out_free: +	ACPI_FREE(output.pointer); +	return ret; +} + +static char *acpi_tad_rt_next_field(char *s, int *val) +{ +	char *p; + +	p = strchr(s, ':'); +	if (!p) +		return NULL; + +	*p = '\0'; +	if (kstrtoint(s, 10, val)) +		return NULL; + +	return p + 1; +} + +static ssize_t time_store(struct device *dev, struct device_attribute *attr, +			  const char *buf, size_t count) +{ +	struct acpi_tad_rt rt; +	char *str, *s; +	int val, ret = -ENODATA; + +	str = kmemdup_nul(buf, count, GFP_KERNEL); +	if (!str) +		return -ENOMEM; + +	s = acpi_tad_rt_next_field(str, &val); +	if (!s) +		goto out_free; + +	rt.year = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.month = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.day = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.hour = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.minute = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.second = val; + +	s = acpi_tad_rt_next_field(s, &val); +	if (!s) +		goto out_free; + +	rt.tz = val; + +	if (kstrtoint(s, 10, &val)) +		goto out_free; + +	rt.daylight = val; + +	rt.valid = 0; +	rt.msec = 0; +	memset(rt.padding, 0, 3); + +	ret = acpi_tad_set_real_time(dev, &rt); + +out_free: +	kfree(str); +	return ret ? ret : count; +} + +static ssize_t time_show(struct device *dev, struct device_attribute *attr, +			 char *buf) +{ +	struct acpi_tad_rt rt; +	int ret; + +	ret = acpi_tad_get_real_time(dev, &rt); +	if (ret) +		return ret; + +	return sprintf(buf, "%u:%u:%u:%u:%u:%u:%d:%u\n", +		       rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second, +		       rt.tz, rt.daylight); +} + +static DEVICE_ATTR(time, S_IRUSR | S_IWUSR, time_show, time_store); + +static struct attribute *acpi_tad_time_attrs[] = { +	&dev_attr_time.attr, +	NULL, +}; +static const struct attribute_group acpi_tad_time_attr_group = { +	.attrs	= acpi_tad_time_attrs, +}; +  static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,  			     u32 value)  { @@ -448,6 +643,12 @@ static int acpi_tad_probe(struct platform_device *pdev)  			goto fail;  	} +	if (caps & ACPI_TAD_RT) { +		ret = sysfs_create_group(&dev->kobj, &acpi_tad_time_attr_group); +		if (ret) +			goto fail; +	} +  	return 0;  fail: diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 71f6f2624deb..b14621da5413 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -65,6 +65,7 @@ acpi-y +=		\  	exresnte.o	\  	exresolv.o	\  	exresop.o	\ +	exserial.o	\  	exstore.o	\  	exstoren.o	\  	exstorob.o	\ diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 704bebbd35b0..b412aa909907 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -229,6 +229,8 @@ acpi_ev_default_region_setup(acpi_handle handle,  acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj); +u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); +  /*   * evsci - SCI (System Control Interrupt) handling/dispatch   */ diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 9613b0115dad..c5b2be0b6613 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -124,6 +124,9 @@ acpi_ex_trace_point(acpi_trace_event_type type,   * exfield - ACPI AML (p-code) execution - field manipulation   */  acpi_status +acpi_ex_get_protocol_buffer_length(u32 protocol_id, u32 *return_length); + +acpi_status  acpi_ex_common_buffer_setup(union acpi_operand_object *obj_desc,  			    u32 buffer_length, u32 * datum_count); @@ -268,6 +271,26 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,  acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info);  /* + * exserial - field_unit support for serial address spaces + */ +acpi_status +acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc, +			union acpi_operand_object **return_buffer); + +acpi_status +acpi_ex_write_serial_bus(union acpi_operand_object *source_desc, +			 union acpi_operand_object *obj_desc, +			 union acpi_operand_object **return_buffer); + +acpi_status +acpi_ex_read_gpio(union acpi_operand_object *obj_desc, void *buffer); + +acpi_status +acpi_ex_write_gpio(union acpi_operand_object *source_desc, +		   union acpi_operand_object *obj_desc, +		   union acpi_operand_object **return_buffer); + +/*   * exsystem - Interface to OS services   */  acpi_status diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 0f28a38a43ea..99b0da899109 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -395,9 +395,9 @@ struct acpi_simple_repair_info {  /* Info for running the _REG methods */  struct acpi_reg_walk_info { -	acpi_adr_space_type space_id;  	u32 function;  	u32 reg_run_count; +	acpi_adr_space_type space_id;  };  /***************************************************************************** diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 250dba02bab6..6c05355447c1 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -432,15 +432,15 @@ typedef enum {   */  typedef enum {  	AML_FIELD_ATTRIB_QUICK = 0x02, -	AML_FIELD_ATTRIB_SEND_RCV = 0x04, +	AML_FIELD_ATTRIB_SEND_RECEIVE = 0x04,  	AML_FIELD_ATTRIB_BYTE = 0x06,  	AML_FIELD_ATTRIB_WORD = 0x08,  	AML_FIELD_ATTRIB_BLOCK = 0x0A, -	AML_FIELD_ATTRIB_MULTIBYTE = 0x0B, -	AML_FIELD_ATTRIB_WORD_CALL = 0x0C, -	AML_FIELD_ATTRIB_BLOCK_CALL = 0x0D, +	AML_FIELD_ATTRIB_BYTES = 0x0B, +	AML_FIELD_ATTRIB_PROCESS_CALL = 0x0C, +	AML_FIELD_ATTRIB_BLOCK_PROCESS_CALL = 0x0D,  	AML_FIELD_ATTRIB_RAW_BYTES = 0x0E, -	AML_FIELD_ATTRIB_RAW_PROCESS = 0x0F +	AML_FIELD_ATTRIB_RAW_PROCESS_BYTES = 0x0F  } AML_ACCESS_ATTRIBUTE;  /* Bit fields in the AML method_flags byte */ diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index e9fb0bf3c8d2..78f9de260d5f 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -417,6 +417,10 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,  			  ACPI_FORMAT_UINT64(obj_desc->region.address),  			  obj_desc->region.length)); +	status = acpi_ut_add_address_range(obj_desc->region.space_id, +					   obj_desc->region.address, +					   obj_desc->region.length, node); +  	/* Now the address and length are valid for this opregion */  	obj_desc->region.flags |= AOPOBJ_DATA_VALID; diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 70c2bd169f66..49decca4e08f 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -653,6 +653,19 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,  	ACPI_FUNCTION_TRACE(ev_execute_reg_methods); +	/* +	 * These address spaces do not need a call to _REG, since the ACPI +	 * specification defines them as: "must always be accessible". Since +	 * they never change state (never become unavailable), no need to ever +	 * call _REG on them. Also, a data_table is not a "real" address space, +	 * so do not call _REG. September 2018. +	 */ +	if ((space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) || +	    (space_id == ACPI_ADR_SPACE_SYSTEM_IO) || +	    (space_id == ACPI_ADR_SPACE_DATA_TABLE)) { +		return_VOID; +	} +  	info.space_id = space_id;  	info.function = function;  	info.reg_run_count = 0; @@ -714,8 +727,8 @@ acpi_ev_reg_run(acpi_handle obj_handle,  	}  	/* -	 * We only care about regions.and objects that are allowed to have address -	 * space handlers +	 * We only care about regions and objects that are allowed to have +	 * address space handlers  	 */  	if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {  		return (AE_OK); diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 39284deedd88..17df5dacd43c 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -16,9 +16,6 @@  #define _COMPONENT          ACPI_EVENTS  ACPI_MODULE_NAME("evrgnini") -/* Local prototypes */ -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); -  /*******************************************************************************   *   * FUNCTION:    acpi_ev_system_memory_region_setup @@ -33,7 +30,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);   * DESCRIPTION: Setup a system_memory operation region   *   ******************************************************************************/ -  acpi_status  acpi_ev_system_memory_region_setup(acpi_handle handle,  				   u32 function, @@ -313,7 +309,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,   *   ******************************************************************************/ -static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) +u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)  {  	acpi_status status;  	struct acpi_pnp_device_id *hid; diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 091415b14fbf..3b3a25d9f0e6 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -193,7 +193,6 @@ acpi_remove_address_space_handler(acpi_handle device,  				 */  				region_obj =  				    handler_obj->address_space.region_list; -  			}  			/* Remove this Handler object from the list */ diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index b272c329d45d..e5798f15793a 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0  /******************************************************************************   * - * Module Name: exfield - ACPI AML (p-code) execution - field manipulation + * Module Name: exfield - AML execution - field_unit read/write   *   * Copyright (C) 2000 - 2018, Intel Corp.   * @@ -16,64 +16,62 @@  #define _COMPONENT          ACPI_EXECUTER  ACPI_MODULE_NAME("exfield") -/* Local prototypes */ -static u32 -acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); +/* + * This table maps the various Attrib protocols to the byte transfer + * length. Used for the generic serial bus. + */ +#define ACPI_INVALID_PROTOCOL_ID        0x80 +#define ACPI_MAX_PROTOCOL_ID            0x0F +const u8 acpi_protocol_lengths[] = { +	ACPI_INVALID_PROTOCOL_ID,	/* 0 - reserved */ +	ACPI_INVALID_PROTOCOL_ID,	/* 1 - reserved */ +	0x00,			/* 2 - ATTRIB_QUICK */ +	ACPI_INVALID_PROTOCOL_ID,	/* 3 - reserved */ +	0x01,			/* 4 - ATTRIB_SEND_RECEIVE */ +	ACPI_INVALID_PROTOCOL_ID,	/* 5 - reserved */ +	0x01,			/* 6 - ATTRIB_BYTE */ +	ACPI_INVALID_PROTOCOL_ID,	/* 7 - reserved */ +	0x02,			/* 8 - ATTRIB_WORD */ +	ACPI_INVALID_PROTOCOL_ID,	/* 9 - reserved */ +	0xFF,			/* A - ATTRIB_BLOCK  */ +	0xFF,			/* B - ATTRIB_BYTES */ +	0x02,			/* C - ATTRIB_PROCESS_CALL */ +	0xFF,			/* D - ATTRIB_BLOCK_PROCESS_CALL */ +	0xFF,			/* E - ATTRIB_RAW_BYTES */ +	0xFF			/* F - ATTRIB_RAW_PROCESS_BYTES */ +};  /*******************************************************************************   * - * FUNCTION:    acpi_ex_get_serial_access_length + * FUNCTION:    acpi_ex_get_protocol_buffer_length   * - * PARAMETERS:  accessor_type   - The type of the protocol indicated by region + * PARAMETERS:  protocol_id     - The type of the protocol indicated by region   *                                field access attributes - *              access_length   - The access length of the region field + *              return_length   - Where the protocol byte transfer length is + *                                returned   * - * RETURN:      Decoded access length + * RETURN:      Status and decoded byte transfer length   *   * DESCRIPTION: This routine returns the length of the generic_serial_bus   *              protocol bytes   *   ******************************************************************************/ -static u32 -acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) +acpi_status +acpi_ex_get_protocol_buffer_length(u32 protocol_id, u32 *return_length)  { -	u32 length; - -	switch (accessor_type) { -	case AML_FIELD_ATTRIB_QUICK: - -		length = 0; -		break; - -	case AML_FIELD_ATTRIB_SEND_RCV: -	case AML_FIELD_ATTRIB_BYTE: - -		length = 1; -		break; - -	case AML_FIELD_ATTRIB_WORD: -	case AML_FIELD_ATTRIB_WORD_CALL: - -		length = 2; -		break; -	case AML_FIELD_ATTRIB_MULTIBYTE: -	case AML_FIELD_ATTRIB_RAW_BYTES: -	case AML_FIELD_ATTRIB_RAW_PROCESS: +	if ((protocol_id > ACPI_MAX_PROTOCOL_ID) || +	    (acpi_protocol_lengths[protocol_id] == ACPI_INVALID_PROTOCOL_ID)) { +		ACPI_ERROR((AE_INFO, +			    "Invalid Field/AccessAs protocol ID: 0x%4.4X", +			    protocol_id)); -		length = access_length; -		break; - -	case AML_FIELD_ATTRIB_BLOCK: -	case AML_FIELD_ATTRIB_BLOCK_CALL: -	default: - -		length = ACPI_GSBUS_BUFFER_SIZE - 2; -		break; +		return (AE_AML_PROTOCOL);  	} -	return (length); +	*return_length = acpi_protocol_lengths[protocol_id]; +	return (AE_OK);  }  /******************************************************************************* @@ -98,10 +96,8 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,  {  	acpi_status status;  	union acpi_operand_object *buffer_desc; -	acpi_size length;  	void *buffer; -	u32 function; -	u16 accessor_type; +	u32 buffer_length;  	ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); @@ -132,60 +128,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,  		    ACPI_ADR_SPACE_GSBUS  		    || obj_desc->field.region_obj->region.space_id ==  		    ACPI_ADR_SPACE_IPMI)) { -		/* -		 * This is an SMBus, GSBus or IPMI read. We must create a buffer to -		 * hold the data and then directly access the region handler. -		 * -		 * Note: SMBus and GSBus protocol value is passed in upper 16-bits -		 * of Function -		 */ -		if (obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_SMBUS) { -			length = ACPI_SMBUS_BUFFER_SIZE; -			function = -			    ACPI_READ | (obj_desc->field.attribute << 16); -		} else if (obj_desc->field.region_obj->region.space_id == -			   ACPI_ADR_SPACE_GSBUS) { -			accessor_type = obj_desc->field.attribute; -			length = -			    acpi_ex_get_serial_access_length(accessor_type, -							     obj_desc->field. -							     access_length); - -			/* -			 * Add additional 2 bytes for the generic_serial_bus data buffer: -			 * -			 *     Status;    (Byte 0 of the data buffer) -			 *     Length;    (Byte 1 of the data buffer) -			 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) -			 */ -			length += 2; -			function = ACPI_READ | (accessor_type << 16); -		} else {	/* IPMI */ - -			length = ACPI_IPMI_BUFFER_SIZE; -			function = ACPI_READ; -		} - -		buffer_desc = acpi_ut_create_buffer_object(length); -		if (!buffer_desc) { -			return_ACPI_STATUS(AE_NO_MEMORY); -		} - -		/* Lock entire transaction if requested */ - -		acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); - -		/* Call the region handler for the read */ -		status = acpi_ex_access_region(obj_desc, 0, -					       ACPI_CAST_PTR(u64, -							     buffer_desc-> -							     buffer.pointer), -					       function); +		/* SMBus, GSBus, IPMI serial */ -		acpi_ex_release_global_lock(obj_desc->common_field.field_flags); -		goto exit; +		status = acpi_ex_read_serial_bus(obj_desc, ret_buffer_desc); +		return_ACPI_STATUS(status);  	}  	/* @@ -198,14 +145,14 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,  	 *  	 * Note: Field.length is in bits.  	 */ -	length = +	buffer_length =  	    (acpi_size)ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); -	if (length > acpi_gbl_integer_byte_width) { +	if (buffer_length > acpi_gbl_integer_byte_width) {  		/* Field is too large for an Integer, create a Buffer instead */ -		buffer_desc = acpi_ut_create_buffer_object(length); +		buffer_desc = acpi_ut_create_buffer_object(buffer_length);  		if (!buffer_desc) {  			return_ACPI_STATUS(AE_NO_MEMORY);  		} @@ -218,47 +165,24 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,  			return_ACPI_STATUS(AE_NO_MEMORY);  		} -		length = acpi_gbl_integer_byte_width; +		buffer_length = acpi_gbl_integer_byte_width;  		buffer = &buffer_desc->integer.value;  	}  	if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&  	    (obj_desc->field.region_obj->region.space_id ==  	     ACPI_ADR_SPACE_GPIO)) { -		/* -		 * For GPIO (general_purpose_io), the Address will be the bit offset -		 * from the previous Connection() operator, making it effectively a -		 * pin number index. The bit_length is the length of the field, which -		 * is thus the number of pins. -		 */ -		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, -				  "GPIO FieldRead [FROM]:  Pin %u Bits %u\n", -				  obj_desc->field.pin_number_index, -				  obj_desc->field.bit_length)); - -		/* Lock entire transaction if requested */ -		acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); +		/* General Purpose I/O */ -		/* Perform the write */ - -		status = -		    acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, -					  ACPI_READ); - -		acpi_ex_release_global_lock(obj_desc->common_field.field_flags); -		if (ACPI_FAILURE(status)) { -			acpi_ut_remove_reference(buffer_desc); -		} else { -			*ret_buffer_desc = buffer_desc; -		} -		return_ACPI_STATUS(status); +		status = acpi_ex_read_gpio(obj_desc, buffer); +		goto exit;  	}  	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,  			  "FieldRead [TO]:   Obj %p, Type %X, Buf %p, ByteLen %X\n",  			  obj_desc, obj_desc->common.type, buffer, -			  (u32) length)); +			  buffer_length));  	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,  			  "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",  			  obj_desc->common_field.bit_length, @@ -271,7 +195,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,  	/* Read from the field */ -	status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); +	status = acpi_ex_extract_from_field(obj_desc, buffer, buffer_length);  	acpi_ex_release_global_lock(obj_desc->common_field.field_flags);  exit: @@ -304,11 +228,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,  			    union acpi_operand_object **result_desc)  {  	acpi_status status; -	u32 length; +	u32 buffer_length;  	void *buffer; -	union acpi_operand_object *buffer_desc; -	u32 function; -	u16 accessor_type;  	ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); @@ -331,130 +252,25 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,  		}  	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&  		   (obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_SMBUS -		    || obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_GSBUS -		    || obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_IPMI)) { -		/* -		 * This is an SMBus, GSBus or IPMI write. We will bypass the entire -		 * field mechanism and handoff the buffer directly to the handler. -		 * For these address spaces, the buffer is bi-directional; on a -		 * write, return data is returned in the same buffer. -		 * -		 * Source must be a buffer of sufficient size: -		 * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or -		 * ACPI_IPMI_BUFFER_SIZE. -		 * -		 * Note: SMBus and GSBus protocol type is passed in upper 16-bits -		 * of Function -		 */ -		if (source_desc->common.type != ACPI_TYPE_BUFFER) { -			ACPI_ERROR((AE_INFO, -				    "SMBus/IPMI/GenericSerialBus write requires " -				    "Buffer, found type %s", -				    acpi_ut_get_object_type_name(source_desc))); - -			return_ACPI_STATUS(AE_AML_OPERAND_TYPE); -		} - -		if (obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_SMBUS) { -			length = ACPI_SMBUS_BUFFER_SIZE; -			function = -			    ACPI_WRITE | (obj_desc->field.attribute << 16); -		} else if (obj_desc->field.region_obj->region.space_id == -			   ACPI_ADR_SPACE_GSBUS) { -			accessor_type = obj_desc->field.attribute; -			length = -			    acpi_ex_get_serial_access_length(accessor_type, -							     obj_desc->field. -							     access_length); - -			/* -			 * Add additional 2 bytes for the generic_serial_bus data buffer: -			 * -			 *     Status;    (Byte 0 of the data buffer) -			 *     Length;    (Byte 1 of the data buffer) -			 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) -			 */ -			length += 2; -			function = ACPI_WRITE | (accessor_type << 16); -		} else {	/* IPMI */ - -			length = ACPI_IPMI_BUFFER_SIZE; -			function = ACPI_WRITE; -		} - -		if (source_desc->buffer.length < length) { -			ACPI_ERROR((AE_INFO, -				    "SMBus/IPMI/GenericSerialBus write requires " -				    "Buffer of length %u, found length %u", -				    length, source_desc->buffer.length)); - -			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); -		} - -		/* Create the bi-directional buffer */ - -		buffer_desc = acpi_ut_create_buffer_object(length); -		if (!buffer_desc) { -			return_ACPI_STATUS(AE_NO_MEMORY); -		} - -		buffer = buffer_desc->buffer.pointer; -		memcpy(buffer, source_desc->buffer.pointer, length); - -		/* Lock entire transaction if requested */ +		    ACPI_ADR_SPACE_GPIO)) { -		acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); +		/* General Purpose I/O */ -		/* -		 * Perform the write (returns status and perhaps data in the -		 * same buffer) -		 */ -		status = -		    acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, function); -		acpi_ex_release_global_lock(obj_desc->common_field.field_flags); - -		*result_desc = buffer_desc; +		status = acpi_ex_write_gpio(source_desc, obj_desc, result_desc);  		return_ACPI_STATUS(status);  	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&  		   (obj_desc->field.region_obj->region.space_id == -		    ACPI_ADR_SPACE_GPIO)) { -		/* -		 * For GPIO (general_purpose_io), we will bypass the entire field -		 * mechanism and handoff the bit address and bit width directly to -		 * the handler. The Address will be the bit offset -		 * from the previous Connection() operator, making it effectively a -		 * pin number index. The bit_length is the length of the field, which -		 * is thus the number of pins. -		 */ -		if (source_desc->common.type != ACPI_TYPE_INTEGER) { -			return_ACPI_STATUS(AE_AML_OPERAND_TYPE); -		} - -		ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, -				  "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X  [TO]: Pin %u Bits %u\n", -				  acpi_ut_get_type_name(source_desc->common. -							type), -				  source_desc->common.type, -				  (u32)source_desc->integer.value, -				  obj_desc->field.pin_number_index, -				  obj_desc->field.bit_length)); - -		buffer = &source_desc->integer.value; - -		/* Lock entire transaction if requested */ - -		acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); +		    ACPI_ADR_SPACE_SMBUS +		    || obj_desc->field.region_obj->region.space_id == +		    ACPI_ADR_SPACE_GSBUS +		    || obj_desc->field.region_obj->region.space_id == +		    ACPI_ADR_SPACE_IPMI)) { -		/* Perform the write */ +		/* SMBus, GSBus, IPMI serial */  		status = -		    acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, -					  ACPI_WRITE); -		acpi_ex_release_global_lock(obj_desc->common_field.field_flags); +		    acpi_ex_write_serial_bus(source_desc, obj_desc, +					     result_desc);  		return_ACPI_STATUS(status);  	} @@ -464,23 +280,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,  	case ACPI_TYPE_INTEGER:  		buffer = &source_desc->integer.value; -		length = sizeof(source_desc->integer.value); +		buffer_length = sizeof(source_desc->integer.value);  		break;  	case ACPI_TYPE_BUFFER:  		buffer = source_desc->buffer.pointer; -		length = source_desc->buffer.length; +		buffer_length = source_desc->buffer.length;  		break;  	case ACPI_TYPE_STRING:  		buffer = source_desc->string.pointer; -		length = source_desc->string.length; +		buffer_length = source_desc->string.length;  		break;  	default: -  		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);  	} @@ -488,7 +303,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,  			  "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",  			  source_desc,  			  acpi_ut_get_type_name(source_desc->common.type), -			  source_desc->common.type, buffer, length)); +			  source_desc->common.type, buffer, buffer_length));  	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,  			  "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n", @@ -505,8 +320,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,  	/* Write to the field */ -	status = acpi_ex_insert_into_field(obj_desc, buffer, length); +	status = acpi_ex_insert_into_field(obj_desc, buffer, buffer_length);  	acpi_ex_release_global_lock(obj_desc->common_field.field_flags); -  	return_ACPI_STATUS(status);  } diff --git a/drivers/acpi/acpica/exserial.c b/drivers/acpi/acpica/exserial.c new file mode 100644 index 000000000000..0d42f30e5b25 --- /dev/null +++ b/drivers/acpi/acpica/exserial.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 +/****************************************************************************** + * + * Module Name: exserial - field_unit support for serial address spaces + * + * Copyright (C) 2000 - 2018, Intel Corp. + * + *****************************************************************************/ + +#include <acpi/acpi.h> +#include "accommon.h" +#include "acdispat.h" +#include "acinterp.h" +#include "amlcode.h" + +#define _COMPONENT          ACPI_EXECUTER +ACPI_MODULE_NAME("exserial") + +/******************************************************************************* + * + * FUNCTION:    acpi_ex_read_gpio + * + * PARAMETERS:  obj_desc            - The named field to read + *              buffer              - Where the return data is returnd + * + * RETURN:      Status + * + * DESCRIPTION: Read from a named field that references a Generic Serial Bus + *              field + * + ******************************************************************************/ +acpi_status acpi_ex_read_gpio(union acpi_operand_object *obj_desc, void *buffer) +{ +	acpi_status status; + +	ACPI_FUNCTION_TRACE_PTR(ex_read_gpio, obj_desc); + +	/* +	 * For GPIO (general_purpose_io), the Address will be the bit offset +	 * from the previous Connection() operator, making it effectively a +	 * pin number index. The bit_length is the length of the field, which +	 * is thus the number of pins. +	 */ +	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, +			  "GPIO FieldRead [FROM]:  Pin %u Bits %u\n", +			  obj_desc->field.pin_number_index, +			  obj_desc->field.bit_length)); + +	/* Lock entire transaction if requested */ + +	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); + +	/* Perform the read */ + +	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, ACPI_READ); + +	acpi_ex_release_global_lock(obj_desc->common_field.field_flags); +	return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ex_write_gpio + * + * PARAMETERS:  source_desc         - Contains data to write. Expect to be + *                                    an Integer object. + *              obj_desc            - The named field + *              result_desc         - Where the return value is returned, if any + * + * RETURN:      Status + * + * DESCRIPTION: Write to a named field that references a General Purpose I/O + *              field. + * + ******************************************************************************/ + +acpi_status +acpi_ex_write_gpio(union acpi_operand_object *source_desc, +		   union acpi_operand_object *obj_desc, +		   union acpi_operand_object **return_buffer) +{ +	acpi_status status; +	void *buffer; + +	ACPI_FUNCTION_TRACE_PTR(ex_write_gpio, obj_desc); + +	/* +	 * For GPIO (general_purpose_io), we will bypass the entire field +	 * mechanism and handoff the bit address and bit width directly to +	 * the handler. The Address will be the bit offset +	 * from the previous Connection() operator, making it effectively a +	 * pin number index. The bit_length is the length of the field, which +	 * is thus the number of pins. +	 */ +	if (source_desc->common.type != ACPI_TYPE_INTEGER) { +		return_ACPI_STATUS(AE_AML_OPERAND_TYPE); +	} + +	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, +			  "GPIO FieldWrite [FROM]: (%s:%X), Value %.8X  [TO]: Pin %u Bits %u\n", +			  acpi_ut_get_type_name(source_desc->common.type), +			  source_desc->common.type, +			  (u32)source_desc->integer.value, +			  obj_desc->field.pin_number_index, +			  obj_desc->field.bit_length)); + +	buffer = &source_desc->integer.value; + +	/* Lock entire transaction if requested */ + +	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); + +	/* Perform the write */ + +	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, ACPI_WRITE); +	acpi_ex_release_global_lock(obj_desc->common_field.field_flags); +	return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ex_read_serial_bus + * + * PARAMETERS:  obj_desc            - The named field to read + *              return_buffer       - Where the return value is returned, if any + * + * RETURN:      Status + * + * DESCRIPTION: Read from a named field that references a serial bus + *              (SMBus, IPMI, or GSBus). + * + ******************************************************************************/ + +acpi_status +acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc, +			union acpi_operand_object **return_buffer) +{ +	acpi_status status; +	u32 buffer_length; +	union acpi_operand_object *buffer_desc; +	u32 function; +	u16 accessor_type; + +	ACPI_FUNCTION_TRACE_PTR(ex_read_serial_bus, obj_desc); + +	/* +	 * This is an SMBus, GSBus or IPMI read. We must create a buffer to +	 * hold the data and then directly access the region handler. +	 * +	 * Note: SMBus and GSBus protocol value is passed in upper 16-bits +	 * of Function +	 * +	 * Common buffer format: +	 *     Status;    (Byte 0 of the data buffer) +	 *     Length;    (Byte 1 of the data buffer) +	 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) +	 */ +	switch (obj_desc->field.region_obj->region.space_id) { +	case ACPI_ADR_SPACE_SMBUS: + +		buffer_length = ACPI_SMBUS_BUFFER_SIZE; +		function = ACPI_READ | (obj_desc->field.attribute << 16); +		break; + +	case ACPI_ADR_SPACE_IPMI: + +		buffer_length = ACPI_IPMI_BUFFER_SIZE; +		function = ACPI_READ; +		break; + +	case ACPI_ADR_SPACE_GSBUS: + +		accessor_type = obj_desc->field.attribute; +		if (accessor_type == AML_FIELD_ATTRIB_RAW_PROCESS_BYTES) { +			ACPI_ERROR((AE_INFO, +				    "Invalid direct read using bidirectional write-then-read protocol")); + +			return_ACPI_STATUS(AE_AML_PROTOCOL); +		} + +		status = +		    acpi_ex_get_protocol_buffer_length(accessor_type, +						       &buffer_length); +		if (ACPI_FAILURE(status)) { +			ACPI_ERROR((AE_INFO, +				    "Invalid protocol ID for GSBus: 0x%4.4X", +				    accessor_type)); + +			return_ACPI_STATUS(status); +		} + +		/* Add header length to get the full size of the buffer */ + +		buffer_length += ACPI_SERIAL_HEADER_SIZE; +		function = ACPI_READ | (accessor_type << 16); +		break; + +	default: +		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); +	} + +	/* Create the local transfer buffer that is returned to the caller */ + +	buffer_desc = acpi_ut_create_buffer_object(buffer_length); +	if (!buffer_desc) { +		return_ACPI_STATUS(AE_NO_MEMORY); +	} + +	/* Lock entire transaction if requested */ + +	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); + +	/* Call the region handler for the write-then-read */ + +	status = acpi_ex_access_region(obj_desc, 0, +				       ACPI_CAST_PTR(u64, +						     buffer_desc->buffer. +						     pointer), function); +	acpi_ex_release_global_lock(obj_desc->common_field.field_flags); + +	*return_buffer = buffer_desc; +	return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION:    acpi_ex_write_serial_bus + * + * PARAMETERS:  source_desc         - Contains data to write + *              obj_desc            - The named field + *              return_buffer       - Where the return value is returned, if any + * + * RETURN:      Status + * + * DESCRIPTION: Write to a named field that references a serial bus + *              (SMBus, IPMI, GSBus). + * + ******************************************************************************/ + +acpi_status +acpi_ex_write_serial_bus(union acpi_operand_object *source_desc, +			 union acpi_operand_object *obj_desc, +			 union acpi_operand_object **return_buffer) +{ +	acpi_status status; +	u32 buffer_length; +	u32 data_length; +	void *buffer; +	union acpi_operand_object *buffer_desc; +	u32 function; +	u16 accessor_type; + +	ACPI_FUNCTION_TRACE_PTR(ex_write_serial_bus, obj_desc); + +	/* +	 * This is an SMBus, GSBus or IPMI write. We will bypass the entire +	 * field mechanism and handoff the buffer directly to the handler. +	 * For these address spaces, the buffer is bidirectional; on a +	 * write, return data is returned in the same buffer. +	 * +	 * Source must be a buffer of sufficient size, these are fixed size: +	 * ACPI_SMBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE. +	 * +	 * Note: SMBus and GSBus protocol type is passed in upper 16-bits +	 * of Function +	 * +	 * Common buffer format: +	 *     Status;    (Byte 0 of the data buffer) +	 *     Length;    (Byte 1 of the data buffer) +	 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) +	 */ +	if (source_desc->common.type != ACPI_TYPE_BUFFER) { +		ACPI_ERROR((AE_INFO, +			    "SMBus/IPMI/GenericSerialBus write requires " +			    "Buffer, found type %s", +			    acpi_ut_get_object_type_name(source_desc))); + +		return_ACPI_STATUS(AE_AML_OPERAND_TYPE); +	} + +	switch (obj_desc->field.region_obj->region.space_id) { +	case ACPI_ADR_SPACE_SMBUS: + +		buffer_length = ACPI_SMBUS_BUFFER_SIZE; +		data_length = ACPI_SMBUS_DATA_SIZE; +		function = ACPI_WRITE | (obj_desc->field.attribute << 16); +		break; + +	case ACPI_ADR_SPACE_IPMI: + +		buffer_length = ACPI_IPMI_BUFFER_SIZE; +		data_length = ACPI_IPMI_DATA_SIZE; +		function = ACPI_WRITE; +		break; + +	case ACPI_ADR_SPACE_GSBUS: + +		accessor_type = obj_desc->field.attribute; +		status = +		    acpi_ex_get_protocol_buffer_length(accessor_type, +						       &buffer_length); +		if (ACPI_FAILURE(status)) { +			ACPI_ERROR((AE_INFO, +				    "Invalid protocol ID for GSBus: 0x%4.4X", +				    accessor_type)); + +			return_ACPI_STATUS(status); +		} + +		/* Add header length to get the full size of the buffer */ + +		buffer_length += ACPI_SERIAL_HEADER_SIZE; +		data_length = source_desc->buffer.pointer[1]; +		function = ACPI_WRITE | (accessor_type << 16); +		break; + +	default: +		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); +	} + +#if 0 +	OBSOLETE ? +	    /* Check for possible buffer overflow */ +	    if (data_length > source_desc->buffer.length) { +		ACPI_ERROR((AE_INFO, +			    "Length in buffer header (%u)(%u) is greater than " +			    "the physical buffer length (%u) and will overflow", +			    data_length, buffer_length, +			    source_desc->buffer.length)); + +		return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); +	} +#endif + +	/* Create the transfer/bidirectional/return buffer */ + +	buffer_desc = acpi_ut_create_buffer_object(buffer_length); +	if (!buffer_desc) { +		return_ACPI_STATUS(AE_NO_MEMORY); +	} + +	/* Copy the input buffer data to the transfer buffer */ + +	buffer = buffer_desc->buffer.pointer; +	memcpy(buffer, source_desc->buffer.pointer, data_length); + +	/* Lock entire transaction if requested */ + +	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); + +	/* +	 * Perform the write (returns status and perhaps data in the +	 * same buffer) +	 */ +	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, function); +	acpi_ex_release_global_lock(obj_desc->common_field.field_flags); + +	*return_buffer = buffer_desc; +	return_ACPI_STATUS(status); +} diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 34fc2f7476ed..0fa01c9e353e 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -147,7 +147,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,  		 * future. Use of this option can cause problems with AML code that  		 * depends upon in-order immediate execution of module-level code.  		 */ -		if (acpi_gbl_group_module_level_code && +		if (!acpi_gbl_execute_tables_as_methods &&  		    (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&  		    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {  			/* @@ -417,6 +417,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)  	union acpi_parse_object *op = NULL;	/* current op */  	struct acpi_parse_state *parser_state;  	u8 *aml_op_start = NULL; +	u8 opcode_length;  	ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state); @@ -540,8 +541,19 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)  						    "Skip parsing opcode %s",  						    acpi_ps_get_opcode_name  						    (walk_state->opcode))); + +					/* +					 * Determine the opcode length before skipping the opcode. +					 * An opcode can be 1 byte or 2 bytes in length. +					 */ +					opcode_length = 1; +					if ((walk_state->opcode & 0xFF00) == +					    AML_EXTENDED_OPCODE) { +						opcode_length = 2; +					}  					walk_state->parser_state.aml = -					    walk_state->aml + 1; +					    walk_state->aml + opcode_length; +  					walk_state->parser_state.aml =  					    acpi_ps_get_next_package_end  					    (&walk_state->parser_state); diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 2f40f71c06db..9011297552af 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -69,8 +69,7 @@ acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)  				"While loading namespace from ACPI tables"));  	} -	if (acpi_gbl_execute_tables_as_methods -	    || !acpi_gbl_group_module_level_code) { +	if (acpi_gbl_execute_tables_as_methods) {  		/*  		 * If the module-level code support is enabled, initialize the objects  		 * in the namespace that remain uninitialized. This runs the executable diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 08f26db2da7e..2a361e22d38d 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1428,7 +1428,7 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,  	return 0;  dma_deconfigure: -	acpi_dma_deconfigure(&pdev->dev); +	arch_teardown_dma_ops(&pdev->dev);  dev_put:  	platform_device_put(pdev); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d2e29a19890d..bb3d96dea6db 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1054,15 +1054,17 @@ void __init acpi_early_init(void)  		goto error0;  	} -	if (!acpi_gbl_execute_tables_as_methods && -	    acpi_gbl_group_module_level_code) { -		status = acpi_load_tables(); -		if (ACPI_FAILURE(status)) { -			printk(KERN_ERR PREFIX -			       "Unable to load the System Description Tables\n"); -			goto error0; -		} -	} +	/* +	 * ACPI 2.0 requires the EC driver to be loaded and work before +	 * the EC device is found in the namespace (i.e. before +	 * acpi_load_tables() is called). +	 * +	 * This is accomplished by looking for the ECDT table, and getting +	 * the EC parameters out of that. +	 * +	 * Ignore the result. Not having an ECDT is not fatal. +	 */ +	status = acpi_ec_ecdt_probe();  #ifdef CONFIG_X86  	if (!acpi_ioapic) { @@ -1133,25 +1135,11 @@ static int __init acpi_bus_init(void)  	acpi_os_initialize1(); -	/* -	 * ACPI 2.0 requires the EC driver to be loaded and work before -	 * the EC device is found in the namespace (i.e. before -	 * acpi_load_tables() is called). -	 * -	 * This is accomplished by looking for the ECDT table, and getting -	 * the EC parameters out of that. -	 */ -	status = acpi_ec_ecdt_probe(); -	/* Ignore result. Not having an ECDT is not fatal. */ - -	if (acpi_gbl_execute_tables_as_methods || -	    !acpi_gbl_group_module_level_code) { -		status = acpi_load_tables(); -		if (ACPI_FAILURE(status)) { -			printk(KERN_ERR PREFIX -			       "Unable to load the System Description Tables\n"); -			goto error1; -		} +	status = acpi_load_tables(); +	if (ACPI_FAILURE(status)) { +		printk(KERN_ERR PREFIX +		       "Unable to load the System Description Tables\n"); +		goto error1;  	}  	status = acpi_enable_subsystem(ACPI_NO_ACPI_ENABLE); diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index d9ce4b162e2c..217a782c3e55 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1061,9 +1061,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)  {  	struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);  	struct cpc_register_resource *highest_reg, *lowest_reg, -		*lowest_non_linear_reg, *nominal_reg, +		*lowest_non_linear_reg, *nominal_reg, *guaranteed_reg,  		*low_freq_reg = NULL, *nom_freq_reg = NULL; -	u64 high, low, nom, min_nonlinear, low_f = 0, nom_f = 0; +	u64 high, low, guaranteed, nom, min_nonlinear, low_f = 0, nom_f = 0;  	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);  	struct cppc_pcc_data *pcc_ss_data = NULL;  	int ret = 0, regs_in_pcc = 0; @@ -1079,6 +1079,7 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)  	nominal_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];  	low_freq_reg = &cpc_desc->cpc_regs[LOWEST_FREQ];  	nom_freq_reg = &cpc_desc->cpc_regs[NOMINAL_FREQ]; +	guaranteed_reg = &cpc_desc->cpc_regs[GUARANTEED_PERF];  	/* Are any of the regs PCC ?*/  	if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || @@ -1107,6 +1108,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)  	cpc_read(cpunum, nominal_reg, &nom);  	perf_caps->nominal_perf = nom; +	cpc_read(cpunum, guaranteed_reg, &guaranteed); +	perf_caps->guaranteed_perf = guaranteed; +  	cpc_read(cpunum, lowest_non_linear_reg, &min_nonlinear);  	perf_caps->lowest_nonlinear_perf = min_nonlinear; diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c index e967c1173ba3..4451877f83b6 100644 --- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -92,8 +92,7 @@ static int __init acpi_custom_method_init(void)  static void __exit acpi_custom_method_exit(void)  { -	if (cm_dentry) -		debugfs_remove(cm_dentry); +	debugfs_remove(cm_dentry);  }  module_init(acpi_custom_method_init); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 3be1433853bf..12ba2bee8789 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -320,7 +320,7 @@ static int acpi_platform_notify(struct device *dev)  	if (!adev)  		goto out; -	if (dev->bus == &platform_bus_type) +	if (dev_is_platform(dev))  		acpi_configure_pmsi_domain(dev);  	if (type && type->setup) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 8df9abfa947b..b48874b8e1ea 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -617,15 +617,18 @@ void acpi_os_stall(u32 us)  }  /* - * Support ACPI 3.0 AML Timer operand - * Returns 64-bit free-running, monotonically increasing timer - * with 100ns granularity + * Support ACPI 3.0 AML Timer operand. Returns a 64-bit free-running, + * monotonically increasing timer with 100ns granularity. Do not use + * ktime_get() to implement this function because this function may get + * called after timekeeping has been suspended. Note: calling this function + * after timekeeping has been suspended may lead to unexpected results + * because when timekeeping is suspended the jiffies counter is not + * incremented. See also timekeeping_suspend().   */  u64 acpi_os_get_timer(void)  { -	u64 time_ns = ktime_to_ns(ktime_get()); -	do_div(time_ns, 100); -	return time_ns; +	return (get_jiffies_64() - INITIAL_JIFFIES) * +		(ACPI_100NSEC_PER_SEC / HZ);  }  acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width) @@ -1129,6 +1132,7 @@ void acpi_os_wait_events_complete(void)  	flush_workqueue(kacpid_wq);  	flush_workqueue(kacpi_notify_wq);  } +EXPORT_SYMBOL(acpi_os_wait_events_complete);  struct acpi_hp_work {  	struct work_struct work; diff --git a/drivers/acpi/pmic/intel_pmic_bxtwc.c b/drivers/acpi/pmic/intel_pmic_bxtwc.c index 886ac8b93cd0..bd7621edd60b 100644 --- a/drivers/acpi/pmic/intel_pmic_bxtwc.c +++ b/drivers/acpi/pmic/intel_pmic_bxtwc.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0  /* - * intel_pmic_bxtwc.c - Intel BXT WhiskeyCove PMIC operation region driver + * Intel BXT WhiskeyCove PMIC operation region driver   *   * Copyright (C) 2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details.   */  #include <linux/init.h> diff --git a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c index f6d73a243d80..7ccd7d9660bc 100644 --- a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c +++ b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * Dollar Cove TI PMIC operation region driver   * Copyright (C) 2014 Intel Corporation. All rights reserved. diff --git a/drivers/acpi/pmic/intel_pmic_chtwc.c b/drivers/acpi/pmic/intel_pmic_chtwc.c index 9912422c8185..078b0448f30a 100644 --- a/drivers/acpi/pmic/intel_pmic_chtwc.c +++ b/drivers/acpi/pmic/intel_pmic_chtwc.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * Intel CHT Whiskey Cove PMIC operation region driver   * Copyright (C) 2017 Hans de Goede <[email protected]>   *   * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:   * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details.   */  #include <linux/acpi.h> diff --git a/drivers/acpi/pmic/intel_pmic_crc.c b/drivers/acpi/pmic/intel_pmic_crc.c index 22c9e374c923..a0f411a6e5ac 100644 --- a/drivers/acpi/pmic/intel_pmic_crc.c +++ b/drivers/acpi/pmic/intel_pmic_crc.c @@ -1,23 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0  /* - * intel_pmic_crc.c - Intel CrystalCove PMIC operation region driver + * Intel CrystalCove PMIC operation region driver   *   * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details.   */ -#include <linux/init.h>  #include <linux/acpi.h> +#include <linux/init.h>  #include <linux/mfd/intel_soc_pmic.h> -#include <linux/regmap.h>  #include <linux/platform_device.h> +#include <linux/regmap.h>  #include "intel_pmic.h"  #define PWR_SOURCE_SELECT	BIT(1) diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c index 316e55174aa9..aadc86db804c 100644 --- a/drivers/acpi/pmic/intel_pmic_xpower.c +++ b/drivers/acpi/pmic/intel_pmic_xpower.c @@ -1,23 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0  /* - * intel_pmic_xpower.c - XPower AXP288 PMIC operation region driver + * XPower AXP288 PMIC operation region driver   *   * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details.   */ -#include <linux/init.h>  #include <linux/acpi.h> +#include <linux/init.h>  #include <linux/mfd/axp20x.h> -#include <linux/regmap.h>  #include <linux/platform_device.h> +#include <linux/regmap.h>  #include "intel_pmic.h"  #define XPOWER_GPADC_LOW	0x5b diff --git a/drivers/acpi/pmic/tps68470_pmic.c b/drivers/acpi/pmic/tps68470_pmic.c index a083de507009..ebd03e472955 100644 --- a/drivers/acpi/pmic/tps68470_pmic.c +++ b/drivers/acpi/pmic/tps68470_pmic.c @@ -10,8 +10,8 @@   */  #include <linux/acpi.h> -#include <linux/mfd/tps68470.h>  #include <linux/init.h> +#include <linux/mfd/tps68470.h>  #include <linux/platform_device.h>  #include <linux/regmap.h> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index d1e26cb599bf..da031b1df6f5 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -338,9 +338,6 @@ static struct acpi_pptt_cache *acpi_find_cache_node(struct acpi_table_header *ta  	return found;  } -/* total number of attributes checked by the properties code */ -#define PPTT_CHECKED_ATTRIBUTES 4 -  /**   * update_cache_properties() - Update cacheinfo for the given processor   * @this_leaf: Kernel cache info structure being updated @@ -357,25 +354,15 @@ static void update_cache_properties(struct cacheinfo *this_leaf,  				    struct acpi_pptt_cache *found_cache,  				    struct acpi_pptt_processor *cpu_node)  { -	int valid_flags = 0; -  	this_leaf->fw_token = cpu_node; -	if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID) { +	if (found_cache->flags & ACPI_PPTT_SIZE_PROPERTY_VALID)  		this_leaf->size = found_cache->size; -		valid_flags++; -	} -	if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID) { +	if (found_cache->flags & ACPI_PPTT_LINE_SIZE_VALID)  		this_leaf->coherency_line_size = found_cache->line_size; -		valid_flags++; -	} -	if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID) { +	if (found_cache->flags & ACPI_PPTT_NUMBER_OF_SETS_VALID)  		this_leaf->number_of_sets = found_cache->number_of_sets; -		valid_flags++; -	} -	if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID) { +	if (found_cache->flags & ACPI_PPTT_ASSOCIATIVITY_VALID)  		this_leaf->ways_of_associativity = found_cache->associativity; -		valid_flags++; -	}  	if (found_cache->flags & ACPI_PPTT_WRITE_POLICY_VALID) {  		switch (found_cache->attributes & ACPI_PPTT_MASK_WRITE_POLICY) {  		case ACPI_PPTT_CACHE_POLICY_WT: @@ -402,11 +389,17 @@ static void update_cache_properties(struct cacheinfo *this_leaf,  		}  	}  	/* -	 * If the above flags are valid, and the cache type is NOCACHE -	 * update the cache type as well. +	 * If cache type is NOCACHE, then the cache hasn't been specified +	 * via other mechanisms.  Update the type if a cache type has been +	 * provided. +	 * +	 * Note, we assume such caches are unified based on conventional system +	 * design and known examples.  Significant work is required elsewhere to +	 * fully support data/instruction only type caches which are only +	 * specified in PPTT.  	 */  	if (this_leaf->type == CACHE_TYPE_NOCACHE && -	    valid_flags == PPTT_CHECKED_ATTRIBUTES) +	    found_cache->flags & ACPI_PPTT_CACHE_TYPE_VALID)  		this_leaf->type = CACHE_TYPE_UNIFIED;  } diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index abb559cd28d7..b2131c4ea124 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -205,6 +205,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,  static void tsc_check_state(int state)  {  	switch (boot_cpu_data.x86_vendor) { +	case X86_VENDOR_HYGON:  	case X86_VENDOR_AMD:  	case X86_VENDOR_INTEL:  	case X86_VENDOR_CENTAUR: diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 295b59271189..96c5e27967f4 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -441,9 +441,13 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)  	/*  	 * The spec requires that bit 4 always be 1. If it's not set, assume -	 * that the implementation doesn't support an SBS charger +	 * that the implementation doesn't support an SBS charger. +	 * +	 * And on some MacBooks a status of 0xffff is always returned, no +	 * matter whether the charger is plugged in or not, which is also +	 * wrong, so ignore the SBS charger for those too.  	 */ -	if (!((status >> 4) & 0x1)) +	if (!((status >> 4) & 0x1) || status == 0xffff)  		return -ENODEV;  	sbs->charger_present = (status >> 15) & 0x1; diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 7a3431018e0a..5008ead4609a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -196,6 +196,7 @@ int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)  	hc->callback = NULL;  	hc->context = NULL;  	mutex_unlock(&hc->lock); +	acpi_os_wait_events_complete();  	return 0;  } @@ -292,6 +293,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device)  	hc = acpi_driver_data(device);  	acpi_ec_remove_query_handler(hc->ec, hc->query_bit); +	acpi_os_wait_events_complete();  	kfree(hc);  	device->driver_data = NULL;  	return 0; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e1b6231cfa1c..bd1c59fb0e17 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1469,16 +1469,6 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)  }  EXPORT_SYMBOL_GPL(acpi_dma_configure); -/** - * acpi_dma_deconfigure - Tear-down DMA configuration for the device. - * @dev: The pointer to the device - */ -void acpi_dma_deconfigure(struct device *dev) -{ -	arch_teardown_dma_ops(dev); -} -EXPORT_SYMBOL_GPL(acpi_dma_deconfigure); -  static void acpi_init_coherency(struct acpi_device *adev)  {  	unsigned long long cca = 0; @@ -1550,6 +1540,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)  	 */  	static const struct acpi_device_id i2c_multi_instantiate_ids[] = {  		{"BSG1160", }, +		{"INT33FE", },  		{}  	}; diff --git a/drivers/acpi/x86/apple.c b/drivers/acpi/x86/apple.c index 51b4cf9f25da..bb1984f6c9fe 100644 --- a/drivers/acpi/x86/apple.c +++ b/drivers/acpi/x86/apple.c @@ -62,7 +62,7 @@ void acpi_extract_apple_properties(struct acpi_device *adev)  	if (!numprops)  		goto out_free; -	valid = kcalloc(BITS_TO_LONGS(numprops), sizeof(long), GFP_KERNEL); +	valid = bitmap_zalloc(numprops, GFP_KERNEL);  	if (!valid)  		goto out_free; @@ -137,5 +137,5 @@ void acpi_extract_apple_properties(struct acpi_device *adev)  out_free:  	ACPI_FREE(props); -	kfree(valid); +	bitmap_free(valid);  } diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index 06c31ec3cc70..9a8e286dd86f 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -54,7 +54,7 @@ static const struct always_present_id always_present_ids[] = {  	 * Bay / Cherry Trail PWM directly poked by GPU driver in win10,  	 * but Linux uses a separate PWM driver, harmless if not used.  	 */ -	ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT1), {}), +	ENTRY("80860F09", "1", ICPU(INTEL_FAM6_ATOM_SILVERMONT), {}),  	ENTRY("80862288", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}),  	/*  	 * The INT0002 device is necessary to clear wakeup interrupt sources |