0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/acpi.h>
0010 #include <linux/component.h>
0011
0012 #include "class.h"
0013
0014 static int typec_aggregate_bind(struct device *dev)
0015 {
0016 return component_bind_all(dev, NULL);
0017 }
0018
0019 static void typec_aggregate_unbind(struct device *dev)
0020 {
0021 component_unbind_all(dev, NULL);
0022 }
0023
0024 static const struct component_master_ops typec_aggregate_ops = {
0025 .bind = typec_aggregate_bind,
0026 .unbind = typec_aggregate_unbind,
0027 };
0028
0029 struct each_port_arg {
0030 struct typec_port *port;
0031 struct component_match *match;
0032 };
0033
0034 static int typec_port_compare(struct device *dev, void *fwnode)
0035 {
0036 return device_match_fwnode(dev, fwnode);
0037 }
0038
0039 static int typec_port_match(struct device *dev, void *data)
0040 {
0041 struct acpi_device *adev = to_acpi_device(dev);
0042 struct each_port_arg *arg = data;
0043 struct acpi_device *con_adev;
0044
0045 con_adev = ACPI_COMPANION(&arg->port->dev);
0046 if (con_adev == adev)
0047 return 0;
0048
0049 if (con_adev->pld_crc == adev->pld_crc)
0050 component_match_add(&arg->port->dev, &arg->match, typec_port_compare,
0051 acpi_fwnode_handle(adev));
0052 return 0;
0053 }
0054
0055 int typec_link_ports(struct typec_port *con)
0056 {
0057 struct each_port_arg arg = { .port = con, .match = NULL };
0058
0059 if (!has_acpi_companion(&con->dev))
0060 return 0;
0061
0062 acpi_bus_for_each_dev(typec_port_match, &arg);
0063 if (!arg.match)
0064 return 0;
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 return component_master_add_with_match(&con->dev, &typec_aggregate_ops, arg.match);
0078 }
0079
0080 void typec_unlink_ports(struct typec_port *con)
0081 {
0082 if (has_acpi_companion(&con->dev))
0083 component_master_del(&con->dev, &typec_aggregate_ops);
0084 }