diff options
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/acpica/tbutils.c | 38 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utresrc.c | 9 | ||||
| -rw-r--r-- | drivers/acpi/arm64/iort.c | 22 | ||||
| -rw-r--r-- | drivers/acpi/battery.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/button.c | 16 | ||||
| -rw-r--r-- | drivers/acpi/device_pm.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/nfit/mce.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 71 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 28 | ||||
| -rw-r--r-- | drivers/acpi/sysfs.c | 7 | 
10 files changed, 98 insertions, 100 deletions
| diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 5a968a78652b..0d2e98920069 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -416,13 +416,18 @@ acpi_tb_get_table(struct acpi_table_desc *table_desc,  		}  	} -	table_desc->validation_count++; -	if (table_desc->validation_count == 0) { -		ACPI_ERROR((AE_INFO, -			    "Table %p, Validation count is zero after increment\n", -			    table_desc)); -		table_desc->validation_count--; -		return_ACPI_STATUS(AE_LIMIT); +	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { +		table_desc->validation_count++; + +		/* +		 * Detect validation_count overflows to ensure that the warning +		 * message will only be printed once. +		 */ +		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { +			ACPI_WARNING((AE_INFO, +				      "Table %p, Validation count overflows\n", +				      table_desc)); +		}  	}  	*out_table = table_desc->pointer; @@ -449,13 +454,20 @@ void acpi_tb_put_table(struct acpi_table_desc *table_desc)  	ACPI_FUNCTION_TRACE(acpi_tb_put_table); -	if (table_desc->validation_count == 0) { -		ACPI_WARNING((AE_INFO, -			      "Table %p, Validation count is zero before decrement\n", -			      table_desc)); -		return_VOID; +	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { +		table_desc->validation_count--; + +		/* +		 * Detect validation_count underflows to ensure that the warning +		 * message will only be printed once. +		 */ +		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { +			ACPI_WARNING((AE_INFO, +				      "Table %p, Validation count underflows\n", +				      table_desc)); +			return_VOID; +		}  	} -	table_desc->validation_count--;  	if (table_desc->validation_count == 0) { diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index e0587c85bafd..ff096d9755b9 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -474,15 +474,6 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,  				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);  			} -			/* -			 * The end_tag opcode must be followed by a zero byte. -			 * Although this byte is technically defined to be a checksum, -			 * in practice, all ASL compilers set this byte to zero. -			 */ -			if (*(aml + 1) != 0) { -				return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); -			} -  			/* Return the pointer to the end_tag if requested */  			if (!user_function) { diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index c5fecf97ee2f..797b28dc7b34 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -666,14 +666,6 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,  	int ret = -ENODEV;  	struct fwnode_handle *iort_fwnode; -	/* -	 * If we already translated the fwspec there -	 * is nothing left to do, return the iommu_ops. -	 */ -	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); -	if (ops) -		return ops; -  	if (node) {  		iort_fwnode = iort_get_fwnode(node);  		if (!iort_fwnode) @@ -735,6 +727,14 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)  	u32 streamid = 0;  	int err; +	/* +	 * If we already translated the fwspec there +	 * is nothing left to do, return the iommu_ops. +	 */ +	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); +	if (ops) +		return ops; +  	if (dev_is_pci(dev)) {  		struct pci_bus *bus = to_pci_dev(dev)->bus;  		u32 rid; @@ -782,6 +782,12 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)  	if (err)  		ops = ERR_PTR(err); +	/* Ignore all other errors apart from EPROBE_DEFER */ +	if (IS_ERR(ops) && (PTR_ERR(ops) != -EPROBE_DEFER)) { +		dev_dbg(dev, "Adding to IOMMU failed: %ld\n", PTR_ERR(ops)); +		ops = NULL; +	} +  	return ops;  } diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index a9a9ab3399d4..d42eeef9d928 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -782,7 +782,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume)  	if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) ||  	    (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) &&              (battery->capacity_now <= battery->alarm))) -		pm_wakeup_hard_event(&battery->device->dev); +		pm_wakeup_event(&battery->device->dev, 0);  	return result;  } diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index b7c2a06963d6..e19f530f1083 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -57,6 +57,7 @@  #define ACPI_BUTTON_LID_INIT_IGNORE	0x00  #define ACPI_BUTTON_LID_INIT_OPEN	0x01 +#define ACPI_BUTTON_LID_INIT_METHOD	0x02  #define _COMPONENT		ACPI_BUTTON_COMPONENT  ACPI_MODULE_NAME("button"); @@ -112,7 +113,7 @@ struct acpi_button {  static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);  static struct acpi_device *lid_device; -static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; +static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;  static unsigned long lid_report_interval __read_mostly = 500;  module_param(lid_report_interval, ulong, 0644); @@ -216,7 +217,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)  	}  	if (state) -		pm_wakeup_hard_event(&device->dev); +		pm_wakeup_event(&device->dev, 0);  	ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);  	if (ret == NOTIFY_DONE) @@ -376,6 +377,9 @@ static void acpi_lid_initialize_state(struct acpi_device *device)  	case ACPI_BUTTON_LID_INIT_OPEN:  		(void)acpi_lid_notify_state(device, 1);  		break; +	case ACPI_BUTTON_LID_INIT_METHOD: +		(void)acpi_lid_update_state(device); +		break;  	case ACPI_BUTTON_LID_INIT_IGNORE:  	default:  		break; @@ -398,7 +402,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)  		} else {  			int keycode; -			pm_wakeup_hard_event(&device->dev); +			pm_wakeup_event(&device->dev, 0);  			if (button->suspended)  				break; @@ -530,7 +534,6 @@ static int acpi_button_add(struct acpi_device *device)  		lid_device = device;  	} -	device_init_wakeup(&device->dev, true);  	printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));  	return 0; @@ -560,6 +563,9 @@ static int param_set_lid_init_state(const char *val, struct kernel_param *kp)  	if (!strncmp(val, "open", sizeof("open") - 1)) {  		lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;  		pr_info("Notify initial lid state as open\n"); +	} else if (!strncmp(val, "method", sizeof("method") - 1)) { +		lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; +		pr_info("Notify initial lid state with _LID return value\n");  	} else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {  		lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;  		pr_info("Do not notify initial lid state\n"); @@ -573,6 +579,8 @@ static int param_get_lid_init_state(char *buffer, struct kernel_param *kp)  	switch (lid_init_state) {  	case ACPI_BUTTON_LID_INIT_OPEN:  		return sprintf(buffer, "open"); +	case ACPI_BUTTON_LID_INIT_METHOD: +		return sprintf(buffer, "method");  	case ACPI_BUTTON_LID_INIT_IGNORE:  		return sprintf(buffer, "ignore");  	default: diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 798d5003a039..993fd31394c8 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -24,7 +24,6 @@  #include <linux/pm_qos.h>  #include <linux/pm_domain.h>  #include <linux/pm_runtime.h> -#include <linux/suspend.h>  #include "internal.h" @@ -400,7 +399,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)  	mutex_lock(&acpi_pm_notifier_lock);  	if (adev->wakeup.flags.notifier_present) { -		pm_wakeup_ws_event(adev->wakeup.ws, 0, true); +		__pm_wakeup_event(adev->wakeup.ws, 0);  		if (adev->wakeup.context.work.func)  			queue_pm_work(&adev->wakeup.context.work);  	} diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c index 3ba1c3472cf9..fd86bec98dea 100644 --- a/drivers/acpi/nfit/mce.c +++ b/drivers/acpi/nfit/mce.c @@ -26,7 +26,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,  	struct nfit_spa *nfit_spa;  	/* We only care about memory errors */ -	if (!(mce->status & MCACOD)) +	if (!mce_is_memory_error(mce))  		return NOTIFY_DONE;  	/* diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e39ec7b7cb67..d53162997f32 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1371,8 +1371,8 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)  	iort_set_dma_mask(dev);  	iommu = iort_iommu_configure(dev); -	if (IS_ERR(iommu)) -		return PTR_ERR(iommu); +	if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER) +		return -EPROBE_DEFER;  	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);  	/* @@ -1428,6 +1428,37 @@ 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) +{ +	bool *is_spi_i2c_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; + +	 /* no need to do more checking */ +	return -1; +} + +static bool acpi_is_spi_i2c_slave(struct acpi_device *device) +{ +	struct list_head resource_list; +	bool is_spi_i2c_slave = false; + +	INIT_LIST_HEAD(&resource_list); +	acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, +			       &is_spi_i2c_slave); +	acpi_dev_free_resource_list(&resource_list); + +	return is_spi_i2c_slave; +} +  void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,  			     int type, unsigned long long sta)  { @@ -1443,6 +1474,7 @@ 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);  	acpi_device_clear_enumerated(device);  	device_initialize(&device->dev);  	dev_set_uevent_suppress(&device->dev, true); @@ -1727,38 +1759,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,  	return AE_OK;  } -static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) -{ -	bool *is_spi_i2c_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; - -	 /* no need to do more checking */ -	return -1; -} -  static void acpi_default_enumeration(struct acpi_device *device)  { -	struct list_head resource_list; -	bool is_spi_i2c_slave = false; -  	/*  	 * Do not enumerate SPI/I2C slaves as they will be enumerated by their  	 * respective parents.  	 */ -	INIT_LIST_HEAD(&resource_list); -	acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, -			       &is_spi_i2c_slave); -	acpi_dev_free_resource_list(&resource_list); -	if (!is_spi_i2c_slave) { +	if (!device->flags.spi_i2c_slave) {  		acpi_create_platform_device(device, NULL);  		acpi_device_set_enumerated(device);  	} else { @@ -1854,7 +1861,7 @@ static void acpi_bus_attach(struct acpi_device *device)  		return;  	device->flags.match_driver = true; -	if (ret > 0) { +	if (ret > 0 && !device->flags.spi_i2c_slave) {  		acpi_device_set_enumerated(device);  		goto ok;  	} @@ -1863,10 +1870,10 @@ static void acpi_bus_attach(struct acpi_device *device)  	if (ret < 0)  		return; -	if (device->pnp.type.platform_id) -		acpi_default_enumeration(device); -	else +	if (!device->pnp.type.platform_id && !device->flags.spi_i2c_slave)  		acpi_device_set_enumerated(device); +	else +		acpi_default_enumeration(device);   ok:  	list_for_each_entry(child, &device->children, node) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index a6574d626340..097d630ab886 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -663,40 +663,14 @@ static int acpi_freeze_prepare(void)  	acpi_os_wait_events_complete();  	if (acpi_sci_irq_valid())  		enable_irq_wake(acpi_sci_irq); -  	return 0;  } -static void acpi_freeze_wake(void) -{ -	/* -	 * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means -	 * that the SCI has triggered while suspended, so cancel the wakeup in -	 * case it has not been a wakeup event (the GPEs will be checked later). -	 */ -	if (acpi_sci_irq_valid() && -	    !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) -		pm_system_cancel_wakeup(); -} - -static void acpi_freeze_sync(void) -{ -	/* -	 * Process all pending events in case there are any wakeup ones. -	 * -	 * The EC driver uses the system workqueue, so that one needs to be -	 * flushed too. -	 */ -	acpi_os_wait_events_complete(); -	flush_scheduled_work(); -} -  static void acpi_freeze_restore(void)  {  	acpi_disable_wakeup_devices(ACPI_STATE_S0);  	if (acpi_sci_irq_valid())  		disable_irq_wake(acpi_sci_irq); -  	acpi_enable_all_runtime_gpes();  } @@ -708,8 +682,6 @@ static void acpi_freeze_end(void)  static const struct platform_freeze_ops acpi_freeze_ops = {  	.begin = acpi_freeze_begin,  	.prepare = acpi_freeze_prepare, -	.wake = acpi_freeze_wake, -	.sync = acpi_freeze_sync,  	.restore = acpi_freeze_restore,  	.end = acpi_freeze_end,  }; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 1b5ee1e0e5a3..e414fabf7315 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -333,14 +333,17 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,  	    container_of(bin_attr, struct acpi_table_attr, attr);  	struct acpi_table_header *table_header = NULL;  	acpi_status status; +	ssize_t rc;  	status = acpi_get_table(table_attr->name, table_attr->instance,  				&table_header);  	if (ACPI_FAILURE(status))  		return -ENODEV; -	return memory_read_from_buffer(buf, count, &offset, -				       table_header, table_header->length); +	rc = memory_read_from_buffer(buf, count, &offset, table_header, +			table_header->length); +	acpi_put_table(table_header); +	return rc;  }  static int acpi_table_attr_init(struct kobject *tables_obj, | 
