Commit e091ba5c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more ACPI updates from Rafael Wysocki:
 "These fix up direct references to the fwnode field in struct device
  and extend ACPI device properties support.

  Specifics:

   - Replace direct references to the fwnode field in struct device with
     dev_fwnode() and device_match_fwnode() (Andy Shevchenko)

   - Make the ACPI code handling device properties support properties
     with buffer values (Sakari Ailus)"

* tag 'acpi-5.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: property: Fix error handling in acpi_init_properties()
  ACPI: VIOT: Do not dereference fwnode in struct device
  ACPI: property: Read buffer properties as integers
  ACPI: property: Add support for parsing buffer property UUID
  ACPI: property: Unify integer value reading functions
  ACPI: property: Switch node property referencing from ifs to a switch
  ACPI: property: Move property ref argument parsing into a new function
  ACPI: property: Use acpi_object_type consistently in property ref parsing
  ACPI: property: Tie data nodes to acpi handles
  ACPI: property: Return type of acpi_add_nondev_subnodes() should be bool
parents 8745889a da2679f2
Loading
Loading
Loading
Loading
+315 −149
Original line number Original line Diff line number Diff line
@@ -55,14 +55,19 @@ static const guid_t ads_guid =
	GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
	GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
		  0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
		  0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);


static const guid_t buffer_prop_guid =
	GUID_INIT(0xedb12dd0, 0x363d, 0x4085,
		  0xa3, 0xd2, 0x49, 0x52, 0x2c, 0xa1, 0x60, 0xc4);

static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
					   const union acpi_object *desc,
					   union acpi_object *desc,
					   struct acpi_device_data *data,
					   struct acpi_device_data *data,
					   struct fwnode_handle *parent);
					   struct fwnode_handle *parent);
static bool acpi_extract_properties(const union acpi_object *desc,
static bool acpi_extract_properties(acpi_handle handle,
				    union acpi_object *desc,
				    struct acpi_device_data *data);
				    struct acpi_device_data *data);


static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
static bool acpi_nondev_subnode_extract(union acpi_object *desc,
					acpi_handle handle,
					acpi_handle handle,
					const union acpi_object *link,
					const union acpi_object *link,
					struct list_head *list,
					struct list_head *list,
@@ -81,7 +86,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
	INIT_LIST_HEAD(&dn->data.properties);
	INIT_LIST_HEAD(&dn->data.properties);
	INIT_LIST_HEAD(&dn->data.subnodes);
	INIT_LIST_HEAD(&dn->data.subnodes);


	result = acpi_extract_properties(desc, &dn->data);
	result = acpi_extract_properties(handle, desc, &dn->data);


	if (handle) {
	if (handle) {
		acpi_handle scope;
		acpi_handle scope;
@@ -155,8 +160,8 @@ static bool acpi_nondev_subnode_ok(acpi_handle scope,
	return acpi_nondev_subnode_data_ok(handle, link, list, parent);
	return acpi_nondev_subnode_data_ok(handle, link, list, parent);
}
}


static int acpi_add_nondev_subnodes(acpi_handle scope,
static bool acpi_add_nondev_subnodes(acpi_handle scope,
				    const union acpi_object *links,
				     union acpi_object *links,
				     struct list_head *list,
				     struct list_head *list,
				     struct fwnode_handle *parent)
				     struct fwnode_handle *parent)
{
{
@@ -164,7 +169,7 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
	int i;
	int i;


	for (i = 0; i < links->package.count; i++) {
	for (i = 0; i < links->package.count; i++) {
		const union acpi_object *link, *desc;
		union acpi_object *link, *desc;
		acpi_handle handle;
		acpi_handle handle;
		bool result;
		bool result;


@@ -204,7 +209,7 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
}
}


static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
					   const union acpi_object *desc,
					   union acpi_object *desc,
					   struct acpi_device_data *data,
					   struct acpi_device_data *data,
					   struct fwnode_handle *parent)
					   struct fwnode_handle *parent)
{
{
@@ -212,7 +217,8 @@ static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,


	/* Look for the ACPI data subnodes GUID. */
	/* Look for the ACPI data subnodes GUID. */
	for (i = 0; i < desc->package.count; i += 2) {
	for (i = 0; i < desc->package.count; i += 2) {
		const union acpi_object *guid, *links;
		const union acpi_object *guid;
		union acpi_object *links;


		guid = &desc->package.elements[i];
		guid = &desc->package.elements[i];
		links = &desc->package.elements[i + 1];
		links = &desc->package.elements[i + 1];
@@ -325,7 +331,7 @@ static bool acpi_is_property_guid(const guid_t *guid)


struct acpi_device_properties *
struct acpi_device_properties *
acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
		    const union acpi_object *properties)
		    union acpi_object *properties)
{
{
	struct acpi_device_properties *props;
	struct acpi_device_properties *props;


@@ -340,7 +346,141 @@ acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
	return props;
	return props;
}
}


static bool acpi_extract_properties(const union acpi_object *desc,
static void acpi_nondev_subnode_tag(acpi_handle handle, void *context)
{
}

static void acpi_untie_nondev_subnodes(struct acpi_device_data *data)
{
	struct acpi_data_node *dn;

	list_for_each_entry(dn, &data->subnodes, sibling) {
		acpi_detach_data(dn->handle, acpi_nondev_subnode_tag);

		acpi_untie_nondev_subnodes(&dn->data);
	}
}

static bool acpi_tie_nondev_subnodes(struct acpi_device_data *data)
{
	struct acpi_data_node *dn;

	list_for_each_entry(dn, &data->subnodes, sibling) {
		acpi_status status;
		bool ret;

		status = acpi_attach_data(dn->handle, acpi_nondev_subnode_tag, dn);
		if (ACPI_FAILURE(status)) {
			acpi_handle_err(dn->handle, "Can't tag data node\n");
			return false;
		}

		ret = acpi_tie_nondev_subnodes(&dn->data);
		if (!ret)
			return ret;
	}

	return true;
}

static void acpi_data_add_buffer_props(acpi_handle handle,
				       struct acpi_device_data *data,
				       union acpi_object *properties)
{
	struct acpi_device_properties *props;
	union acpi_object *package;
	size_t alloc_size;
	unsigned int i;
	u32 *count;

	if (check_mul_overflow((size_t)properties->package.count,
			       sizeof(*package) + sizeof(void *),
			       &alloc_size) ||
	    check_add_overflow(sizeof(*props) + sizeof(*package), alloc_size,
			       &alloc_size)) {
		acpi_handle_warn(handle,
				 "can't allocate memory for %u buffer props",
				 properties->package.count);
		return;
	}

	props = kvzalloc(alloc_size, GFP_KERNEL);
	if (!props)
		return;

	props->guid = &buffer_prop_guid;
	props->bufs = (void *)(props + 1);
	props->properties = (void *)(props->bufs + properties->package.count);

	/* Outer package */
	package = props->properties;
	package->type = ACPI_TYPE_PACKAGE;
	package->package.elements = package + 1;
	count = &package->package.count;
	*count = 0;

	/* Inner packages */
	package++;

	for (i = 0; i < properties->package.count; i++) {
		struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
		union acpi_object *property = &properties->package.elements[i];
		union acpi_object *prop, *obj, *buf_obj;
		acpi_status status;

		if (property->type != ACPI_TYPE_PACKAGE ||
		    property->package.count != 2) {
			acpi_handle_warn(handle,
					 "buffer property %u has %u entries\n",
					 i, property->package.count);
			continue;
		}

		prop = &property->package.elements[0];
		obj = &property->package.elements[1];

		if (prop->type != ACPI_TYPE_STRING ||
		    obj->type != ACPI_TYPE_STRING) {
			acpi_handle_warn(handle,
					 "wrong object types %u and %u\n",
					 prop->type, obj->type);
			continue;
		}

		status = acpi_evaluate_object_typed(handle, obj->string.pointer,
						    NULL, &buf,
						    ACPI_TYPE_BUFFER);
		if (ACPI_FAILURE(status)) {
			acpi_handle_warn(handle,
					 "can't evaluate \"%*pE\" as buffer\n",
					 obj->string.length,
					 obj->string.pointer);
			continue;
		}

		package->type = ACPI_TYPE_PACKAGE;
		package->package.elements = prop;
		package->package.count = 2;

		buf_obj = buf.pointer;

		/* Replace the string object with a buffer object */
		obj->type = ACPI_TYPE_BUFFER;
		obj->buffer.length = buf_obj->buffer.length;
		obj->buffer.pointer = buf_obj->buffer.pointer;

		props->bufs[i] = buf.pointer;
		package++;
		(*count)++;
	}

	if (*count)
		list_add(&props->list, &data->properties);
	else
		kvfree(props);
}

static bool acpi_extract_properties(acpi_handle scope, union acpi_object *desc,
				    struct acpi_device_data *data)
				    struct acpi_device_data *data)
{
{
	int i;
	int i;
@@ -350,7 +490,8 @@ static bool acpi_extract_properties(const union acpi_object *desc,


	/* Look for the device properties GUID. */
	/* Look for the device properties GUID. */
	for (i = 0; i < desc->package.count; i += 2) {
	for (i = 0; i < desc->package.count; i += 2) {
		const union acpi_object *guid, *properties;
		const union acpi_object *guid;
		union acpi_object *properties;


		guid = &desc->package.elements[i];
		guid = &desc->package.elements[i];
		properties = &desc->package.elements[i + 1];
		properties = &desc->package.elements[i + 1];
@@ -364,6 +505,12 @@ static bool acpi_extract_properties(const union acpi_object *desc,
		    properties->type != ACPI_TYPE_PACKAGE)
		    properties->type != ACPI_TYPE_PACKAGE)
			break;
			break;


		if (guid_equal((guid_t *)guid->buffer.pointer,
			       &buffer_prop_guid)) {
			acpi_data_add_buffer_props(scope, data, properties);
			continue;
		}

		if (!acpi_is_property_guid((guid_t *)guid->buffer.pointer))
		if (!acpi_is_property_guid((guid_t *)guid->buffer.pointer))
			continue;
			continue;


@@ -410,7 +557,7 @@ void acpi_init_properties(struct acpi_device *adev)
	if (ACPI_FAILURE(status))
	if (ACPI_FAILURE(status))
		goto out;
		goto out;


	if (acpi_extract_properties(buf.pointer, &adev->data)) {
	if (acpi_extract_properties(adev->handle, buf.pointer, &adev->data)) {
		adev->data.pointer = buf.pointer;
		adev->data.pointer = buf.pointer;
		if (acpi_of)
		if (acpi_of)
			acpi_init_of_compatible(adev);
			acpi_init_of_compatible(adev);
@@ -422,6 +569,9 @@ void acpi_init_properties(struct acpi_device *adev)
	if (!adev->data.pointer) {
	if (!adev->data.pointer) {
		acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
		acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n");
		ACPI_FREE(buf.pointer);
		ACPI_FREE(buf.pointer);
	} else {
		if (!acpi_tie_nondev_subnodes(&adev->data))
			acpi_untie_nondev_subnodes(&adev->data);
	}
	}


 out:
 out:
@@ -438,8 +588,14 @@ static void acpi_free_device_properties(struct list_head *list)
	struct acpi_device_properties *props, *tmp;
	struct acpi_device_properties *props, *tmp;


	list_for_each_entry_safe(props, tmp, list, list) {
	list_for_each_entry_safe(props, tmp, list, list) {
		u32 i;

		list_del(&props->list);
		list_del(&props->list);
		kfree(props);
		/* Buffer data properties were separately allocated */
		if (props->bufs)
			for (i = 0; i < props->properties->package.count; i++)
				ACPI_FREE(props->bufs[i]);
		kvfree(props);
	}
	}
}
}


@@ -462,6 +618,7 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list)


void acpi_free_properties(struct acpi_device *adev)
void acpi_free_properties(struct acpi_device *adev)
{
{
	acpi_untie_nondev_subnodes(&adev->data);
	acpi_destroy_nondev_subnodes(&adev->data.subnodes);
	acpi_destroy_nondev_subnodes(&adev->data.subnodes);
	ACPI_FREE((void *)adev->data.pointer);
	ACPI_FREE((void *)adev->data.pointer);
	adev->data.of_compatible = NULL;
	adev->data.of_compatible = NULL;
@@ -633,6 +790,58 @@ acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
	return NULL;
	return NULL;
}
}


static int acpi_get_ref_args(struct fwnode_reference_args *args,
			     struct fwnode_handle *ref_fwnode,
			     const union acpi_object **element,
			     const union acpi_object *end, size_t num_args)
{
	u32 nargs = 0, i;

	/*
	 * Find the referred data extension node under the
	 * referred device node.
	 */
	for (; *element < end && (*element)->type == ACPI_TYPE_STRING;
	     (*element)++) {
		const char *child_name = (*element)->string.pointer;

		ref_fwnode = acpi_fwnode_get_named_child_node(ref_fwnode, child_name);
		if (!ref_fwnode)
			return -EINVAL;
	}

	/*
	 * Assume the following integer elements are all args. Stop counting on
	 * the first reference or end of the package arguments. In case of
	 * neither reference, nor integer, return an error, we can't parse it.
	 */
	for (i = 0; (*element) + i < end && i < num_args; i++) {
		acpi_object_type type = (*element)[i].type;

		if (type == ACPI_TYPE_LOCAL_REFERENCE)
			break;

		if (type == ACPI_TYPE_INTEGER)
			nargs++;
		else
			return -EINVAL;
	}

	if (nargs > NR_FWNODE_REFERENCE_ARGS)
		return -EINVAL;

	if (args) {
		args->fwnode = ref_fwnode;
		args->nargs = nargs;
		for (i = 0; i < nargs; i++)
			args->args[i] = (*element)[i].integer.value;
	}

	(*element) += nargs;

	return 0;
}

/**
/**
 * __acpi_node_get_property_reference - returns handle to the referenced object
 * __acpi_node_get_property_reference - returns handle to the referenced object
 * @fwnode: Firmware node to get the property from
 * @fwnode: Firmware node to get the property from
@@ -686,11 +895,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
	if (ret)
	if (ret)
		return ret == -EINVAL ? -ENOENT : -EINVAL;
		return ret == -EINVAL ? -ENOENT : -EINVAL;


	/*
	switch (obj->type) {
	 * The simplest case is when the value is a single reference.  Just
	case ACPI_TYPE_LOCAL_REFERENCE:
	 * return that reference then.
		/* Plain single reference without arguments. */
	 */
	if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
		if (index)
		if (index)
			return -ENOENT;
			return -ENOENT;


@@ -701,8 +908,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
		args->fwnode = acpi_fwnode_handle(device);
		args->fwnode = acpi_fwnode_handle(device);
		args->nargs = 0;
		args->nargs = 0;
		return 0;
		return 0;
	}
	case ACPI_TYPE_PACKAGE:

		/*
		/*
		 * If it is not a single reference, then it is a package of
		 * If it is not a single reference, then it is a package of
		 * references followed by number of ints as follows:
		 * references followed by number of ints as follows:
@@ -712,8 +918,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
		 * The index argument is then used to determine which reference
		 * The index argument is then used to determine which reference
		 * the caller wants (along with the arguments).
		 * the caller wants (along with the arguments).
		 */
		 */
	if (obj->type != ACPI_TYPE_PACKAGE)
		break;
	default:
		return -EINVAL;
		return -EINVAL;
	}

	if (index >= obj->package.count)
	if (index >= obj->package.count)
		return -ENOENT;
		return -ENOENT;


@@ -721,66 +930,30 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
	end = element + obj->package.count;
	end = element + obj->package.count;


	while (element < end) {
	while (element < end) {
		u32 nargs, i;
		switch (element->type) {

		case ACPI_TYPE_LOCAL_REFERENCE:
		if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
			struct fwnode_handle *ref_fwnode;

			device = acpi_fetch_acpi_dev(element->reference.handle);
			device = acpi_fetch_acpi_dev(element->reference.handle);
			if (!device)
			if (!device)
				return -EINVAL;
				return -EINVAL;


			nargs = 0;
			element++;
			element++;


			/*
			ret = acpi_get_ref_args(idx == index ? args : NULL,
			 * Find the referred data extension node under the
						acpi_fwnode_handle(device),
			 * referred device node.
						&element, end, num_args);
			 */
			if (ret < 0)
			for (ref_fwnode = acpi_fwnode_handle(device);
				return ret;
			     element < end && element->type == ACPI_TYPE_STRING;
			     element++) {
				ref_fwnode = acpi_fwnode_get_named_child_node(
					ref_fwnode, element->string.pointer);
				if (!ref_fwnode)
					return -EINVAL;
			}

			/*
			 * Assume the following integer elements are all args.
			 * Stop counting on the first reference or end of the
			 * package arguments. In case of neither reference,
			 * nor integer, return an error, we can't parse it.
			 */
			for (i = 0; element + i < end && i < num_args; i++) {
				int type = element[i].type;

				if (type == ACPI_TYPE_LOCAL_REFERENCE)
					break;
				if (type == ACPI_TYPE_INTEGER)
					nargs++;
				else
					return -EINVAL;
			}

			if (nargs > NR_FWNODE_REFERENCE_ARGS)
				return -EINVAL;

			if (idx == index) {
				args->fwnode = ref_fwnode;
				args->nargs = nargs;
				for (i = 0; i < nargs; i++)
					args->args[i] = element[i].integer.value;


			if (idx == index)
				return 0;
				return 0;
			}


			element += nargs;
			break;
		} else if (element->type == ACPI_TYPE_INTEGER) {
		case ACPI_TYPE_INTEGER:
			if (idx == index)
			if (idx == index)
				return -ENOENT;
				return -ENOENT;
			element++;
			element++;
		} else {
			break;
		default:
			return -EINVAL;
			return -EINVAL;
		}
		}


@@ -852,67 +1025,37 @@ static int acpi_data_prop_read_single(const struct acpi_device_data *data,
	return ret;
	return ret;
}
}


static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val,
#define acpi_copy_property_array_uint(items, val, nval)			\
				       size_t nval)
	({								\
{
		typeof(items) __items = items;				\
	int i;
		typeof(val) __val = val;				\

		typeof(nval) __nval = nval;				\
	for (i = 0; i < nval; i++) {
		size_t i;						\
		if (items[i].type != ACPI_TYPE_INTEGER)
		int ret = 0;						\
			return -EPROTO;
									\
		if (items[i].integer.value > U8_MAX)
		for (i = 0; i < __nval; i++) {				\
			return -EOVERFLOW;
			if (__items->type == ACPI_TYPE_BUFFER) {	\

				__val[i] = __items->buffer.pointer[i];	\
		val[i] = items[i].integer.value;
				continue;				\
	}
			}						\
	return 0;
			if (__items[i].type != ACPI_TYPE_INTEGER) {	\
}
				ret = -EPROTO;				\

				break;					\
static int acpi_copy_property_array_u16(const union acpi_object *items,
			}						\
					u16 *val, size_t nval)
			if (__items[i].integer.value > _Generic(__val,	\
{
								u8: U8_MAX, \
	int i;
								u16: U16_MAX, \

								u32: U32_MAX, \
	for (i = 0; i < nval; i++) {
								u64: U64_MAX, \
		if (items[i].type != ACPI_TYPE_INTEGER)
								default: 0U)) { \
			return -EPROTO;
				ret = -EOVERFLOW;			\
		if (items[i].integer.value > U16_MAX)
				break;					\
			return -EOVERFLOW;
			}						\

									\
		val[i] = items[i].integer.value;
			__val[i] = __items[i].integer.value;		\
	}
		}							\
	return 0;
		ret;							\
}
	})

static int acpi_copy_property_array_u32(const union acpi_object *items,
					u32 *val, size_t nval)
{
	int i;

	for (i = 0; i < nval; i++) {
		if (items[i].type != ACPI_TYPE_INTEGER)
			return -EPROTO;
		if (items[i].integer.value > U32_MAX)
			return -EOVERFLOW;

		val[i] = items[i].integer.value;
	}
	return 0;
}

static int acpi_copy_property_array_u64(const union acpi_object *items,
					u64 *val, size_t nval)
{
	int i;

	for (i = 0; i < nval; i++) {
		if (items[i].type != ACPI_TYPE_INTEGER)
			return -EPROTO;

		val[i] = items[i].integer.value;
	}
	return 0;
}


static int acpi_copy_property_array_string(const union acpi_object *items,
static int acpi_copy_property_array_string(const union acpi_object *items,
					   char **val, size_t nval)
					   char **val, size_t nval)
@@ -954,31 +1097,54 @@ static int acpi_data_prop_read(const struct acpi_device_data *data,
	}
	}


	ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
	ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj);
	if (ret && proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64)
		ret = acpi_data_get_property(data, propname, ACPI_TYPE_BUFFER,
					     &obj);
	if (ret)
	if (ret)
		return ret;
		return ret;


	if (!val)
	if (!val) {
		if (obj->type == ACPI_TYPE_BUFFER)
			return obj->buffer.length;

		return obj->package.count;
		return obj->package.count;
	}


	if (proptype != DEV_PROP_STRING && nval > obj->package.count)
	switch (proptype) {
	case DEV_PROP_STRING:
		break;
	case DEV_PROP_U8 ... DEV_PROP_U64:
		if (obj->type == ACPI_TYPE_BUFFER) {
			if (nval > obj->buffer.length)
				return -EOVERFLOW;
			break;
		}
		fallthrough;
	default:
		if (nval > obj->package.count)
			return -EOVERFLOW;
			return -EOVERFLOW;
		break;
	}
	if (nval == 0)
	if (nval == 0)
		return -EINVAL;
		return -EINVAL;


	if (obj->type != ACPI_TYPE_BUFFER)
		items = obj->package.elements;
		items = obj->package.elements;
	else
		items = obj;


	switch (proptype) {
	switch (proptype) {
	case DEV_PROP_U8:
	case DEV_PROP_U8:
		ret = acpi_copy_property_array_u8(items, (u8 *)val, nval);
		ret = acpi_copy_property_array_uint(items, (u8 *)val, nval);
		break;
		break;
	case DEV_PROP_U16:
	case DEV_PROP_U16:
		ret = acpi_copy_property_array_u16(items, (u16 *)val, nval);
		ret = acpi_copy_property_array_uint(items, (u16 *)val, nval);
		break;
		break;
	case DEV_PROP_U32:
	case DEV_PROP_U32:
		ret = acpi_copy_property_array_u32(items, (u32 *)val, nval);
		ret = acpi_copy_property_array_uint(items, (u32 *)val, nval);
		break;
		break;
	case DEV_PROP_U64:
	case DEV_PROP_U64:
		ret = acpi_copy_property_array_u64(items, (u64 *)val, nval);
		ret = acpi_copy_property_array_uint(items, (u64 *)val, nval);
		break;
		break;
	case DEV_PROP_STRING:
	case DEV_PROP_STRING:
		ret = acpi_copy_property_array_string(
		ret = acpi_copy_property_array_string(
+3 −3
Original line number Original line Diff line number Diff line
@@ -88,7 +88,7 @@ static int __init viot_get_pci_iommu_fwnode(struct viot_iommu *viommu,
		return -ENODEV;
		return -ENODEV;
	}
	}


	fwnode = pdev->dev.fwnode;
	fwnode = dev_fwnode(&pdev->dev);
	if (!fwnode) {
	if (!fwnode) {
		/*
		/*
		 * PCI devices aren't necessarily described by ACPI. Create a
		 * PCI devices aren't necessarily described by ACPI. Create a
@@ -101,7 +101,7 @@ static int __init viot_get_pci_iommu_fwnode(struct viot_iommu *viommu,
		}
		}
		set_primary_fwnode(&pdev->dev, fwnode);
		set_primary_fwnode(&pdev->dev, fwnode);
	}
	}
	viommu->fwnode = pdev->dev.fwnode;
	viommu->fwnode = dev_fwnode(&pdev->dev);
	pci_dev_put(pdev);
	pci_dev_put(pdev);
	return 0;
	return 0;
}
}
@@ -314,7 +314,7 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu,
		return -ENODEV;
		return -ENODEV;


	/* We're not translating ourself */
	/* We're not translating ourself */
	if (viommu->fwnode == dev->fwnode)
	if (device_match_fwnode(dev, viommu->fwnode))
		return -EINVAL;
		return -EINVAL;


	ops = iommu_ops_from_fwnode(viommu->fwnode);
	ops = iommu_ops_from_fwnode(viommu->fwnode);
+2 −1
Original line number Original line Diff line number Diff line
@@ -344,8 +344,9 @@ struct acpi_device_physical_node {


struct acpi_device_properties {
struct acpi_device_properties {
	const guid_t *guid;
	const guid_t *guid;
	const union acpi_object *properties;
	union acpi_object *properties;
	struct list_head list;
	struct list_head list;
	void **bufs;
};
};


/* ACPI Device Specific Data (_DSD) */
/* ACPI Device Specific Data (_DSD) */
+1 −1
Original line number Original line Diff line number Diff line
@@ -1251,7 +1251,7 @@ static inline bool acpi_dev_has_props(const struct acpi_device *adev)


struct acpi_device_properties *
struct acpi_device_properties *
acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
		    const union acpi_object *properties);
		    union acpi_object *properties);


int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname,
int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname,
		       void **valptr);
		       void **valptr);