Skip to content

Commit 12cd73c

Browse files
Guomin Chenopsiff
authored andcommitted
Add a property reference count interface for ACPI.
This patch extends the property handling framework to provide a reference count query interface for ACPI properties. Signed-off-by: "wenxue.ding" <Wenxue.Ding@cixtech.com> Signed-off-by: Guomin Chen <Guomin.Chen@cixtech.com>
1 parent 5b32dff commit 12cd73c

6 files changed

Lines changed: 94 additions & 0 deletions

File tree

drivers/acpi/property.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,64 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
10091009
}
10101010
EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
10111011

1012+
int __acpi_node_count_property_reference(const struct fwnode_handle *fwnode,
1013+
const char *propname)
1014+
{
1015+
const union acpi_object *element, *end;
1016+
const union acpi_object *obj;
1017+
const struct acpi_device_data *data;
1018+
struct acpi_device *device;
1019+
int ret, idx = 0;
1020+
1021+
data = acpi_device_data_of_node(fwnode);
1022+
if (!data)
1023+
return -ENOENT;
1024+
1025+
ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
1026+
if (ret)
1027+
return ret == -EINVAL ? -ENOENT : -EINVAL;
1028+
1029+
switch (obj->type) {
1030+
case ACPI_TYPE_LOCAL_REFERENCE:
1031+
return 1;
1032+
case ACPI_TYPE_PACKAGE:
1033+
break;
1034+
default:
1035+
return -EINVAL;
1036+
}
1037+
1038+
element = obj->package.elements;
1039+
end = element + obj->package.count;
1040+
1041+
while (element < end) {
1042+
switch (element->type) {
1043+
case ACPI_TYPE_LOCAL_REFERENCE:
1044+
device = acpi_fetch_acpi_dev(element->reference.handle);
1045+
if (!device)
1046+
return -EINVAL;
1047+
1048+
element++;
1049+
1050+
ret = acpi_get_ref_args(NULL, acpi_fwnode_handle(device),
1051+
&element, end, NR_FWNODE_REFERENCE_ARGS);
1052+
if (ret < 0)
1053+
return ret;
1054+
1055+
break;
1056+
case ACPI_TYPE_INTEGER:
1057+
element++;
1058+
break;
1059+
default:
1060+
return -EINVAL;
1061+
}
1062+
1063+
idx++;
1064+
}
1065+
1066+
return idx;
1067+
}
1068+
EXPORT_SYMBOL_GPL(__acpi_node_count_property_reference);
1069+
10121070
static int acpi_data_prop_read_single(const struct acpi_device_data *data,
10131071
const char *propname,
10141072
enum dev_prop_type proptype, void *val)
@@ -1536,6 +1594,13 @@ acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
15361594
args_count, args);
15371595
}
15381596

1597+
static int
1598+
acpi_fwnode_count_reference_with_args(const struct fwnode_handle *fwnode,
1599+
const char *list_name, const char *cells_name)
1600+
{
1601+
return __acpi_node_count_property_reference(fwnode, list_name);
1602+
}
1603+
15391604
static const char *acpi_fwnode_get_name(const struct fwnode_handle *fwnode)
15401605
{
15411606
const struct acpi_device *adev;
@@ -1641,6 +1706,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode,
16411706
.graph_get_port_parent = acpi_fwnode_get_parent, \
16421707
.graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
16431708
.irq_get = acpi_fwnode_irq_get, \
1709+
.property_count_reference_with_args = acpi_fwnode_count_reference_with_args, \
16441710
}; \
16451711
EXPORT_SYMBOL_GPL(ops)
16461712

drivers/base/property.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,18 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
543543
}
544544
EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
545545

546+
int fwnode_count_reference_with_args(const struct fwnode_handle *fwnode,
547+
const char *list_name, const char *cells_name)
548+
{
549+
550+
if (IS_ERR_OR_NULL(fwnode))
551+
return -ENOENT;
552+
553+
return fwnode_call_int_op(fwnode,
554+
property_count_reference_with_args, list_name, cells_name);
555+
}
556+
EXPORT_SYMBOL_GPL(fwnode_count_reference_with_args);
557+
546558
/**
547559
* fwnode_find_reference - Find named reference to a fwnode_handle
548560
* @fwnode: Firmware node where to look for the reference

drivers/of/property.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,13 @@ static int of_fwnode_add_links(struct fwnode_handle *fwnode)
14311431
return 0;
14321432
}
14331433

1434+
static int of_count_phandle_with_fwnode_args(
1435+
const struct fwnode_handle *fwnode,
1436+
const char *list_name, const char *cells_name)
1437+
{
1438+
return of_count_phandle_with_args(to_of_node(fwnode), list_name, cells_name);
1439+
}
1440+
14341441
const struct fwnode_operations of_fwnode_ops = {
14351442
.get = of_fwnode_get,
14361443
.put = of_fwnode_put,
@@ -1454,5 +1461,6 @@ const struct fwnode_operations of_fwnode_ops = {
14541461
.iomap = of_fwnode_iomap,
14551462
.irq_get = of_fwnode_irq_get,
14561463
.add_links = of_fwnode_add_links,
1464+
.property_count_reference_with_args = of_count_phandle_with_fwnode_args,
14571465
};
14581466
EXPORT_SYMBOL_GPL(of_fwnode_ops);

include/linux/acpi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,8 @@ int acpi_dev_get_property(const struct acpi_device *adev, const char *name,
13031303
int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
13041304
const char *name, size_t index, size_t num_args,
13051305
struct fwnode_reference_args *args);
1306+
int __acpi_node_count_property_reference(const struct fwnode_handle *fwnode,
1307+
const char *name);
13061308

13071309
static inline int acpi_node_get_property_reference(
13081310
const struct fwnode_handle *fwnode,

include/linux/fwnode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ struct fwnode_operations {
171171
void __iomem *(*iomap)(struct fwnode_handle *fwnode, int index);
172172
int (*irq_get)(const struct fwnode_handle *fwnode, unsigned int index);
173173
int (*add_links)(struct fwnode_handle *fwnode);
174+
int (*property_count_reference_with_args)(
175+
const struct fwnode_handle *fwnode, const char *list_name,
176+
const char *cells_name);
174177

175178
DEEPIN_KABI_RESERVE(1)
176179
DEEPIN_KABI_RESERVE(2)

include/linux/property.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
129129
unsigned int nargs, unsigned int index,
130130
struct fwnode_reference_args *args);
131131

132+
int fwnode_count_reference_with_args(const struct fwnode_handle *fwnode,
133+
const char *list_name, const char *cells_name);
134+
132135
struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
133136
const char *name,
134137
unsigned int index);

0 commit comments

Comments
 (0)