如果bios 通过acpi 表传递给kernel如下code,要如何得到GPIo number呢?
Package () {
"cs-gpios",
Package () {
^GPIO, 19, 0, 0,
^GPIO, 20, 0, 0,
0,
^GPIO, 21, 0, 0,
}
}
这里的gpio都属于cs-gpios的属性,因此在kernel中可以通过下面的code 拿到
struct acpi_reference_args args;
ret = acpi_node_get_property_reference(dev->fwnode,"cs-gpios", 0, &args);
这里的第三个参数0,代表去GPIO, 19, 0, 0
如果第三个参数传递的是2的话,则返回的是0
int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *propname, size_t index, size_t num_args,
struct acpi_reference_args *args)
{
const union acpi_object *element, *end;
const union acpi_object *obj;
struct acpi_device_data *data;
struct acpi_device *device;
int ret, idx = 0;
data = acpi_device_data_of_node(fwnode);
if (!data)
return -EINVAL;
ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
if (ret)
return ret;
/*
* The simplest case is when the value is a single reference. Just
* return that reference then.
*/
if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
if (index)
return -EINVAL;
ret = acpi_bus_get_device(obj->reference.handle, &device);
if (ret)
return ret;
// 这里以single mode 为例,原来通过会得到这个propname 所属的device。
args->adev = device;
args->nargs = 0;
return 0;
}
}
从__acpi_node_get_property_reference 中可以知道会给struct acpi_reference_args *args中的device赋值,这样就可以这个device得到fwnode。下面是acpi_node_get_property_reference的经典用法
/* try to find port-idx-in-ae first */
ret = acpi_node_get_property_reference(dev->fwnode,
"ae-handle", 0, &args);
if (ret) {
dev_err(dev, "not find ae-handle\n");
goto out_read_prop_fail;
}
priv->fwnode = acpi_fwnode_handle(args.adev);
Package () {
"cs-gpios",
Package () {
^GPIO, 19, 0, 0,
^GPIO, 20, 0, 0,
0,
^GPIO, 21, 0, 0,
}
}
这里的gpio都属于cs-gpios的属性,因此在kernel中可以通过下面的code 拿到
struct acpi_reference_args args;
ret = acpi_node_get_property_reference(dev->fwnode,"cs-gpios", 0, &args);
这里的第三个参数0,代表去GPIO, 19, 0, 0
如果第三个参数传递的是2的话,则返回的是0
int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *propname, size_t index, size_t num_args,
struct acpi_reference_args *args)
{
const union acpi_object *element, *end;
const union acpi_object *obj;
struct acpi_device_data *data;
struct acpi_device *device;
int ret, idx = 0;
data = acpi_device_data_of_node(fwnode);
if (!data)
return -EINVAL;
ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
if (ret)
return ret;
/*
* The simplest case is when the value is a single reference. Just
* return that reference then.
*/
if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) {
if (index)
return -EINVAL;
ret = acpi_bus_get_device(obj->reference.handle, &device);
if (ret)
return ret;
// 这里以single mode 为例,原来通过会得到这个propname 所属的device。
args->adev = device;
args->nargs = 0;
return 0;
}
}
从__acpi_node_get_property_reference 中可以知道会给struct acpi_reference_args *args中的device赋值,这样就可以这个device得到fwnode。下面是acpi_node_get_property_reference的经典用法
/* try to find port-idx-in-ae first */
ret = acpi_node_get_property_reference(dev->fwnode,
"ae-handle", 0, &args);
if (ret) {
dev_err(dev, "not find ae-handle\n");
goto out_read_prop_fail;
}
priv->fwnode = acpi_fwnode_handle(args.adev);