forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/soundwire/slave.c
....@@ -2,9 +2,11 @@
22 // Copyright(c) 2015-17 Intel Corporation.
33
44 #include <linux/acpi.h>
5
+#include <linux/of.h>
56 #include <linux/soundwire/sdw.h>
67 #include <linux/soundwire/sdw_type.h>
78 #include "bus.h"
9
+#include "sysfs_local.h"
810
911 static void sdw_slave_release(struct device *dev)
1012 {
....@@ -13,11 +15,18 @@
1315 kfree(slave);
1416 }
1517
16
-static int sdw_slave_add(struct sdw_bus *bus,
17
- struct sdw_slave_id *id, struct fwnode_handle *fwnode)
18
+struct device_type sdw_slave_type = {
19
+ .name = "sdw_slave",
20
+ .release = sdw_slave_release,
21
+ .uevent = sdw_slave_uevent,
22
+};
23
+
24
+int sdw_slave_add(struct sdw_bus *bus,
25
+ struct sdw_slave_id *id, struct fwnode_handle *fwnode)
1826 {
1927 struct sdw_slave *slave;
2028 int ret;
29
+ int i;
2130
2231 slave = kzalloc(sizeof(*slave), GFP_KERNEL);
2332 if (!slave)
....@@ -28,16 +37,33 @@
2837 slave->dev.parent = bus->dev;
2938 slave->dev.fwnode = fwnode;
3039
31
- /* name shall be sdw:link:mfg:part:class:unique */
32
- dev_set_name(&slave->dev, "sdw:%x:%x:%x:%x:%x",
33
- bus->link_id, id->mfg_id, id->part_id,
34
- id->class_id, id->unique_id);
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,
44
+ id->class_id);
45
+ } else {
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);
50
+ }
3551
36
- slave->dev.release = sdw_slave_release;
3752 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;
3856 slave->bus = bus;
3957 slave->status = SDW_SLAVE_UNATTACHED;
58
+ init_completion(&slave->enumeration_complete);
59
+ init_completion(&slave->initialization_complete);
4060 slave->dev_num = 0;
61
+ init_completion(&slave->probe_complete);
62
+ slave->probed = false;
63
+ slave->first_interrupt_done = false;
64
+
65
+ for (i = 0; i < SDW_MAX_PORTS; i++)
66
+ init_completion(&slave->port_ready[i]);
4167
4268 mutex_lock(&bus->bus_lock);
4369 list_add_tail(&slave->node, &bus->slaves);
....@@ -55,12 +81,45 @@
5581 list_del(&slave->node);
5682 mutex_unlock(&bus->bus_lock);
5783 put_device(&slave->dev);
84
+
85
+ return ret;
5886 }
87
+ sdw_slave_debugfs_init(slave);
5988
6089 return ret;
6190 }
6291
6392 #if IS_ENABLED(CONFIG_ACPI)
93
+
94
+static bool find_slave(struct sdw_bus *bus,
95
+ struct acpi_device *adev,
96
+ struct sdw_slave_id *id)
97
+{
98
+ unsigned long long addr;
99
+ unsigned int link_id;
100
+ acpi_status status;
101
+
102
+ status = acpi_evaluate_integer(adev->handle,
103
+ METHOD_NAME__ADR, NULL, &addr);
104
+
105
+ if (ACPI_FAILURE(status)) {
106
+ dev_err(bus->dev, "_ADR resolution failed: %x\n",
107
+ status);
108
+ return false;
109
+ }
110
+
111
+ /* Extract link id from ADR, Bit 51 to 48 (included) */
112
+ link_id = SDW_DISCO_LINK_ID(addr);
113
+
114
+ /* Check for link_id match */
115
+ if (link_id != bus->link_id)
116
+ return false;
117
+
118
+ sdw_extract_slave_id(bus, addr, id);
119
+
120
+ return true;
121
+}
122
+
64123 /*
65124 * sdw_acpi_find_slaves() - Find Slave devices in Master ACPI node
66125 * @bus: SDW bus instance
....@@ -70,6 +129,7 @@
70129 int sdw_acpi_find_slaves(struct sdw_bus *bus)
71130 {
72131 struct acpi_device *adev, *parent;
132
+ struct acpi_device *adev2, *parent2;
73133
74134 parent = ACPI_COMPANION(bus->dev);
75135 if (!parent) {
....@@ -78,28 +138,46 @@
78138 }
79139
80140 list_for_each_entry(adev, &parent->children, node) {
81
- unsigned long long addr;
82141 struct sdw_slave_id id;
83
- unsigned int link_id;
84
- acpi_status status;
142
+ struct sdw_slave_id id2;
143
+ bool ignore_unique_id = true;
85144
86
- status = acpi_evaluate_integer(adev->handle,
87
- METHOD_NAME__ADR, NULL, &addr);
88
-
89
- if (ACPI_FAILURE(status)) {
90
- dev_err(bus->dev, "_ADR resolution failed: %x\n",
91
- status);
92
- return status;
93
- }
94
-
95
- /* Extract link id from ADR, Bit 51 to 48 (included) */
96
- link_id = (addr >> 48) & GENMASK(3, 0);
97
-
98
- /* Check for link_id match */
99
- if (link_id != bus->link_id)
145
+ if (!find_slave(bus, adev, &id))
100146 continue;
101147
102
- sdw_extract_slave_id(bus, addr, &id);
148
+ /* brute-force O(N^2) search for duplicates */
149
+ parent2 = parent;
150
+ list_for_each_entry(adev2, &parent2->children, node) {
151
+
152
+ if (adev == adev2)
153
+ continue;
154
+
155
+ if (!find_slave(bus, adev2, &id2))
156
+ continue;
157
+
158
+ if (id.sdw_version != id2.sdw_version ||
159
+ id.mfg_id != id2.mfg_id ||
160
+ id.part_id != id2.part_id ||
161
+ id.class_id != id2.class_id)
162
+ continue;
163
+
164
+ if (id.unique_id != id2.unique_id) {
165
+ dev_dbg(bus->dev,
166
+ "Valid unique IDs %x %x for Slave mfg %x part %d\n",
167
+ id.unique_id, id2.unique_id,
168
+ id.mfg_id, id.part_id);
169
+ ignore_unique_id = false;
170
+ } else {
171
+ dev_err(bus->dev,
172
+ "Invalid unique IDs %x %x for Slave mfg %x part %d\n",
173
+ id.unique_id, id2.unique_id,
174
+ id.mfg_id, id.part_id);
175
+ return -ENODEV;
176
+ }
177
+ }
178
+
179
+ if (ignore_unique_id)
180
+ id.unique_id = SDW_IGNORED_UNIQUE_ID;
103181
104182 /*
105183 * don't error check for sdw_slave_add as we want to continue
....@@ -112,3 +190,54 @@
112190 }
113191
114192 #endif
193
+
194
+/*
195
+ * sdw_of_find_slaves() - Find Slave devices in master device tree node
196
+ * @bus: SDW bus instance
197
+ *
198
+ * Scans Master DT node for SDW child Slave devices and registers it.
199
+ */
200
+int sdw_of_find_slaves(struct sdw_bus *bus)
201
+{
202
+ struct device *dev = bus->dev;
203
+ struct device_node *node;
204
+
205
+ for_each_child_of_node(bus->dev->of_node, node) {
206
+ int link_id, ret, len;
207
+ unsigned int sdw_version;
208
+ const char *compat = NULL;
209
+ struct sdw_slave_id id;
210
+ const __be32 *addr;
211
+
212
+ compat = of_get_property(node, "compatible", NULL);
213
+ if (!compat)
214
+ continue;
215
+
216
+ ret = sscanf(compat, "sdw%01x%04hx%04hx%02hhx", &sdw_version,
217
+ &id.mfg_id, &id.part_id, &id.class_id);
218
+
219
+ if (ret != 4) {
220
+ dev_err(dev, "Invalid compatible string found %s\n",
221
+ compat);
222
+ continue;
223
+ }
224
+
225
+ addr = of_get_property(node, "reg", &len);
226
+ if (!addr || (len < 2 * sizeof(u32))) {
227
+ dev_err(dev, "Invalid Link and Instance ID\n");
228
+ continue;
229
+ }
230
+
231
+ link_id = be32_to_cpup(addr++);
232
+ id.unique_id = be32_to_cpup(addr);
233
+ id.sdw_version = sdw_version;
234
+
235
+ /* Check for link_id match */
236
+ if (link_id != bus->link_id)
237
+ continue;
238
+
239
+ sdw_slave_add(bus, &id, of_fwnode_handle(node));
240
+ }
241
+
242
+ return 0;
243
+}