Commit 0f318baa authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-apei', 'acpi-properties', 'acpi-sbs' and 'acpi-thermal'

Merge ACPI APEI changes, ACPI device properties handling update, ACPI
SBS driver fixes and ACPI thermal driver cleanup for 6.4-rc1:

 - Make the APEI error injection code warn on invalid arguments when
   explicitly indicated by platform (Shuai Xue).

 - Add CXL error types to the error injection code in APEI (Tony Luck).

 - Refactor acpi_data_prop_read_single() (Andy Shevchenko).

 - Fix two issues in the ACPI SBS driver (Armin Wolf).

 - Replace ternary operator with min_t() in the generic ACPI thermal
   zone driver (Jiangshan Yi).

* acpi-apei:
  ACPI: APEI: EINJ: warn on invalid argument when explicitly indicated by platform
  ACPI: APEI: EINJ: Add CXL error types

* acpi-properties:
  ACPI: property: Refactor acpi_data_prop_read_single()

* acpi-sbs:
  ACPI: SBS: Fix handling of Smart Battery Selectors
  ACPI: EC: Fix oops when removing custom query handlers
  ACPI: EC: Limit explicit removal of query handlers to custom query handlers

* acpi-thermal:
  ACPI: thermal: Replace ternary operator with min_t()
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -489,9 +489,15 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
	if (rc)
		return rc;
	val = apei_exec_ctx_get_output(&ctx);
	if (val != EINJ_STATUS_SUCCESS)
	if (val == EINJ_STATUS_FAIL)
		return -EBUSY;
	else if (val == EINJ_STATUS_INVAL)
		return -EINVAL;

	/*
	 * The error is injected into the platform successfully, then it needs
	 * to trigger the error.
	 */
	rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE);
	if (rc)
		return rc;
@@ -584,6 +590,12 @@ static const char * const einj_error_type_string[] = {
	"0x00000200\tPlatform Correctable\n",
	"0x00000400\tPlatform Uncorrectable non-fatal\n",
	"0x00000800\tPlatform Uncorrectable fatal\n",
	"0x00001000\tCXL.cache Protocol Correctable\n",
	"0x00002000\tCXL.cache Protocol Uncorrectable non-fatal\n",
	"0x00004000\tCXL.cache Protocol Uncorrectable fatal\n",
	"0x00008000\tCXL.mem Protocol Correctable\n",
	"0x00010000\tCXL.mem Protocol Uncorrectable non-fatal\n",
	"0x00020000\tCXL.mem Protocol Uncorrectable fatal\n",
};

static int available_error_type_show(struct seq_file *m, void *v)
+15 −3
Original line number Diff line number Diff line
@@ -1083,9 +1083,12 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
			      acpi_handle handle, acpi_ec_query_func func,
			      void *data)
{
	struct acpi_ec_query_handler *handler =
	    kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
	struct acpi_ec_query_handler *handler;

	if (!handle && !func)
		return -EINVAL;

	handler = kzalloc(sizeof(*handler), GFP_KERNEL);
	if (!handler)
		return -ENOMEM;

@@ -1097,6 +1100,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
	kref_init(&handler->kref);
	list_add(&handler->node, &ec->list);
	mutex_unlock(&ec->mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
@@ -1109,9 +1113,16 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,

	mutex_lock(&ec->mutex);
	list_for_each_entry_safe(handler, tmp, &ec->list, node) {
		if (remove_all || query_bit == handler->query_bit) {
		/*
		 * When remove_all is false, only remove custom query handlers
		 * which have handler->func set. This is done to preserve query
		 * handlers discovered thru ACPI, as they should continue handling
		 * EC queries.
		 */
		if (remove_all || (handler->func && handler->query_bit == query_bit)) {
			list_del_init(&handler->node);
			list_add(&handler->node, &free_list);

		}
	}
	mutex_unlock(&ec->mutex);
@@ -1122,6 +1133,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
{
	acpi_ec_remove_query_handlers(ec, false, query_bit);
	flush_workqueue(ec_query_wq);
}
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);

+34 −46
Original line number Diff line number Diff line
@@ -971,10 +971,12 @@ static int acpi_data_prop_read_single(const struct acpi_device_data *data,
				      enum dev_prop_type proptype, void *val)
{
	const union acpi_object *obj;
	int ret;
	int ret = 0;

	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) {
	if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64)
		ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj);
	else if (proptype == DEV_PROP_STRING)
		ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
	if (ret)
		return ret;

@@ -982,49 +984,35 @@ static int acpi_data_prop_read_single(const struct acpi_device_data *data,
	case DEV_PROP_U8:
		if (obj->integer.value > U8_MAX)
			return -EOVERFLOW;

		if (val)
			*(u8 *)val = obj->integer.value;

		break;
	case DEV_PROP_U16:
		if (obj->integer.value > U16_MAX)
			return -EOVERFLOW;

		if (val)
			*(u16 *)val = obj->integer.value;

		break;
	case DEV_PROP_U32:
		if (obj->integer.value > U32_MAX)
			return -EOVERFLOW;

		if (val)
			*(u32 *)val = obj->integer.value;

		break;
		default:
	case DEV_PROP_U64:
		if (val)
			*(u64 *)val = obj->integer.value;

		break;
		}

		if (!val)
			return 1;
	} else if (proptype == DEV_PROP_STRING) {
		ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj);
		if (ret)
			return ret;

	case DEV_PROP_STRING:
		if (val)
			*(char **)val = obj->string.pointer;

		return 1;
	} else {
		ret = -EINVAL;
	default:
		return -EINVAL;
	}
	return ret;

	/* When no storage provided return number of available values */
	return val ? 0 : 1;
}

#define acpi_copy_property_array_uint(items, val, nval)			\
+18 −9
Original line number Diff line number Diff line
@@ -473,23 +473,32 @@ static const struct device_attribute alarm_attr = {
   -------------------------------------------------------------------------- */
static int acpi_battery_read(struct acpi_battery *battery)
{
	int result = 0, saved_present = battery->present;
	int result, saved_present = battery->present;
	u16 state;

	if (battery->sbs->manager_present) {
		result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
				ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
		if (!result)
		if (result)
			return result;

		battery->present = state & (1 << battery->id);
		state &= 0x0fff;
		if (!battery->present)
			return 0;

		/* Masking necessary for Smart Battery Selectors */
		state = 0x0fff;
		state |= 1 << (battery->id + 12);
		acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
				  ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
	} else if (battery->id == 0)
	} else {
		if (battery->id == 0) {
			battery->present = 1;

	if (result || !battery->present)
		return result;
		} else {
			if (!battery->present)
				return 0;
		}
	}

	if (saved_present != battery->present) {
		battery->update_time = 0;
+3 −4
Original line number Diff line number Diff line
@@ -419,9 +419,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
					 * the next higher trip point
					 */
					tz->trips.active[i-1].temperature =
						(tz->trips.active[i-2].temperature <
						celsius_to_deci_kelvin(act) ?
						tz->trips.active[i-2].temperature :
						min_t(unsigned long,
						      tz->trips.active[i-2].temperature,
						      celsius_to_deci_kelvin(act));

				break;