1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
4 #include <linux/acpi.h>
6 #include <linux/soundwire/sdw.h>
7 #include <linux/soundwire/sdw_type.h>
9 #include "sysfs_local.h"
11 static void sdw_slave_release(struct device
*dev
)
13 struct sdw_slave
*slave
= dev_to_sdw_dev(dev
);
18 struct device_type sdw_slave_type
= {
20 .release
= sdw_slave_release
,
21 .uevent
= sdw_slave_uevent
,
24 int sdw_slave_add(struct sdw_bus
*bus
,
25 struct sdw_slave_id
*id
, struct fwnode_handle
*fwnode
)
27 struct sdw_slave
*slave
;
31 slave
= kzalloc(sizeof(*slave
), GFP_KERNEL
);
35 /* Initialize data structure */
36 memcpy(&slave
->id
, id
, sizeof(*id
));
37 slave
->dev
.parent
= bus
->dev
;
38 slave
->dev
.fwnode
= fwnode
;
40 if (id
->unique_id
== SDW_IGNORED_UNIQUE_ID
) {
41 /* name shall be sdw:link:mfg:part:class */
42 dev_set_name(&slave
->dev
, "sdw:%x:%x:%x:%x",
43 bus
->link_id
, id
->mfg_id
, id
->part_id
,
46 /* name shall be sdw:link:mfg:part:class:unique */
47 dev_set_name(&slave
->dev
, "sdw:%x:%x:%x:%x:%x",
48 bus
->link_id
, id
->mfg_id
, id
->part_id
,
49 id
->class_id
, id
->unique_id
);
52 slave
->dev
.bus
= &sdw_bus_type
;
53 slave
->dev
.of_node
= of_node_get(to_of_node(fwnode
));
54 slave
->dev
.type
= &sdw_slave_type
;
55 slave
->dev
.groups
= sdw_slave_status_attr_groups
;
57 slave
->status
= SDW_SLAVE_UNATTACHED
;
58 init_completion(&slave
->enumeration_complete
);
59 init_completion(&slave
->initialization_complete
);
61 init_completion(&slave
->probe_complete
);
62 slave
->probed
= false;
63 slave
->first_interrupt_done
= false;
65 for (i
= 0; i
< SDW_MAX_PORTS
; i
++)
66 init_completion(&slave
->port_ready
[i
]);
68 mutex_lock(&bus
->bus_lock
);
69 list_add_tail(&slave
->node
, &bus
->slaves
);
70 mutex_unlock(&bus
->bus_lock
);
72 ret
= device_register(&slave
->dev
);
74 dev_err(bus
->dev
, "Failed to add slave: ret %d\n", ret
);
77 * On err, don't free but drop ref as this will be freed
78 * when release method is invoked.
80 mutex_lock(&bus
->bus_lock
);
81 list_del(&slave
->node
);
82 mutex_unlock(&bus
->bus_lock
);
83 put_device(&slave
->dev
);
87 sdw_slave_debugfs_init(slave
);
91 EXPORT_SYMBOL(sdw_slave_add
);
93 #if IS_ENABLED(CONFIG_ACPI)
95 static bool find_slave(struct sdw_bus
*bus
,
96 struct acpi_device
*adev
,
97 struct sdw_slave_id
*id
)
100 unsigned int link_id
;
103 status
= acpi_evaluate_integer(adev
->handle
,
104 METHOD_NAME__ADR
, NULL
, &addr
);
106 if (ACPI_FAILURE(status
)) {
107 dev_err(bus
->dev
, "_ADR resolution failed: %x\n",
112 if (bus
->ops
->override_adr
)
113 addr
= bus
->ops
->override_adr(bus
, addr
);
118 /* Extract link id from ADR, Bit 51 to 48 (included) */
119 link_id
= SDW_DISCO_LINK_ID(addr
);
121 /* Check for link_id match */
122 if (link_id
!= bus
->link_id
)
125 sdw_extract_slave_id(bus
, addr
, id
);
131 * sdw_acpi_find_slaves() - Find Slave devices in Master ACPI node
132 * @bus: SDW bus instance
134 * Scans Master ACPI node for SDW child Slave devices and registers it.
136 int sdw_acpi_find_slaves(struct sdw_bus
*bus
)
138 struct acpi_device
*adev
, *parent
;
139 struct acpi_device
*adev2
, *parent2
;
141 parent
= ACPI_COMPANION(bus
->dev
);
143 dev_err(bus
->dev
, "Can't find parent for acpi bind\n");
147 list_for_each_entry(adev
, &parent
->children
, node
) {
148 struct sdw_slave_id id
;
149 struct sdw_slave_id id2
;
150 bool ignore_unique_id
= true;
152 if (!find_slave(bus
, adev
, &id
))
155 /* brute-force O(N^2) search for duplicates */
157 list_for_each_entry(adev2
, &parent2
->children
, node
) {
162 if (!find_slave(bus
, adev2
, &id2
))
165 if (id
.sdw_version
!= id2
.sdw_version
||
166 id
.mfg_id
!= id2
.mfg_id
||
167 id
.part_id
!= id2
.part_id
||
168 id
.class_id
!= id2
.class_id
)
171 if (id
.unique_id
!= id2
.unique_id
) {
173 "Valid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
174 id
.unique_id
, id2
.unique_id
, id
.mfg_id
, id
.part_id
);
175 ignore_unique_id
= false;
178 "Invalid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
179 id
.unique_id
, id2
.unique_id
, id
.mfg_id
, id
.part_id
);
184 if (ignore_unique_id
)
185 id
.unique_id
= SDW_IGNORED_UNIQUE_ID
;
188 * don't error check for sdw_slave_add as we want to continue
191 sdw_slave_add(bus
, &id
, acpi_fwnode_handle(adev
));
200 * sdw_of_find_slaves() - Find Slave devices in master device tree node
201 * @bus: SDW bus instance
203 * Scans Master DT node for SDW child Slave devices and registers it.
205 int sdw_of_find_slaves(struct sdw_bus
*bus
)
207 struct device
*dev
= bus
->dev
;
208 struct device_node
*node
;
210 for_each_child_of_node(bus
->dev
->of_node
, node
) {
211 int link_id
, ret
, len
;
212 unsigned int sdw_version
;
213 const char *compat
= NULL
;
214 struct sdw_slave_id id
;
217 compat
= of_get_property(node
, "compatible", NULL
);
221 ret
= sscanf(compat
, "sdw%01x%04hx%04hx%02hhx", &sdw_version
,
222 &id
.mfg_id
, &id
.part_id
, &id
.class_id
);
225 dev_err(dev
, "Invalid compatible string found %s\n",
230 addr
= of_get_property(node
, "reg", &len
);
231 if (!addr
|| (len
< 2 * sizeof(u32
))) {
232 dev_err(dev
, "Invalid Link and Instance ID\n");
236 link_id
= be32_to_cpup(addr
++);
237 id
.unique_id
= be32_to_cpup(addr
);
238 id
.sdw_version
= sdw_version
;
240 /* Check for link_id match */
241 if (link_id
!= bus
->link_id
)
244 sdw_slave_add(bus
, &id
, of_fwnode_handle(node
));