1 | // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) |
2 | // Copyright(c) 2015-22 Intel Corporation. |
3 | |
4 | /* |
5 | * Soundwire Intel Manager Driver |
6 | */ |
7 | |
8 | #include <linux/acpi.h> |
9 | #include <linux/debugfs.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/module.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> |
14 | #include <linux/auxiliary_bus.h> |
15 | #include <sound/pcm_params.h> |
16 | #include <linux/pm_runtime.h> |
17 | #include <sound/soc.h> |
18 | #include <linux/soundwire/sdw_registers.h> |
19 | #include <linux/soundwire/sdw.h> |
20 | #include <linux/soundwire/sdw_intel.h> |
21 | #include "cadence_master.h" |
22 | #include "bus.h" |
23 | #include "intel.h" |
24 | #include "intel_auxdevice.h" |
25 | |
26 | #define INTEL_MASTER_SUSPEND_DELAY_MS 3000 |
27 | |
28 | /* |
29 | * debug/config flags for the Intel SoundWire Master. |
30 | * |
31 | * Since we may have multiple masters active, we can have up to 8 |
32 | * flags reused in each byte, with master0 using the ls-byte, etc. |
33 | */ |
34 | |
35 | #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0) |
36 | #define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1) |
37 | #define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2) |
38 | #define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3) |
39 | |
40 | static int md_flags; |
41 | module_param_named(sdw_md_flags, md_flags, int, 0444); |
42 | MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)" ); |
43 | |
44 | struct wake_capable_part { |
45 | const u16 mfg_id; |
46 | const u16 part_id; |
47 | }; |
48 | |
49 | static struct wake_capable_part wake_capable_list[] = { |
50 | {0x025d, 0x5682}, |
51 | {0x025d, 0x700}, |
52 | {0x025d, 0x711}, |
53 | {0x025d, 0x1712}, |
54 | {0x025d, 0x1713}, |
55 | {0x025d, 0x1716}, |
56 | {0x025d, 0x1717}, |
57 | {0x025d, 0x712}, |
58 | {0x025d, 0x713}, |
59 | {0x025d, 0x714}, |
60 | {0x025d, 0x715}, |
61 | {0x025d, 0x716}, |
62 | {0x025d, 0x717}, |
63 | {0x025d, 0x722}, |
64 | }; |
65 | |
66 | static bool is_wake_capable(struct sdw_slave *slave) |
67 | { |
68 | int i; |
69 | |
70 | for (i = 0; i < ARRAY_SIZE(wake_capable_list); i++) |
71 | if (slave->id.part_id == wake_capable_list[i].part_id && |
72 | slave->id.mfg_id == wake_capable_list[i].mfg_id) |
73 | return true; |
74 | return false; |
75 | } |
76 | |
77 | static int generic_pre_bank_switch(struct sdw_bus *bus) |
78 | { |
79 | struct sdw_cdns *cdns = bus_to_cdns(bus); |
80 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
81 | |
82 | return sdw->link_res->hw_ops->pre_bank_switch(sdw); |
83 | } |
84 | |
85 | static int generic_post_bank_switch(struct sdw_bus *bus) |
86 | { |
87 | struct sdw_cdns *cdns = bus_to_cdns(bus); |
88 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
89 | |
90 | return sdw->link_res->hw_ops->post_bank_switch(sdw); |
91 | } |
92 | |
93 | static void generic_new_peripheral_assigned(struct sdw_bus *bus, |
94 | struct sdw_slave *slave, |
95 | int dev_num) |
96 | { |
97 | struct sdw_cdns *cdns = bus_to_cdns(bus); |
98 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
99 | int dev_num_min; |
100 | int dev_num_max; |
101 | bool wake_capable = slave->prop.wake_capable || is_wake_capable(slave); |
102 | |
103 | if (wake_capable) { |
104 | dev_num_min = SDW_INTEL_DEV_NUM_IDA_MIN; |
105 | dev_num_max = SDW_MAX_DEVICES; |
106 | } else { |
107 | dev_num_min = 1; |
108 | dev_num_max = SDW_INTEL_DEV_NUM_IDA_MIN - 1; |
109 | } |
110 | |
111 | /* paranoia check, this should never happen */ |
112 | if (dev_num < dev_num_min || dev_num > dev_num_max) { |
113 | dev_err(bus->dev, "%s: invalid dev_num %d, wake supported %d\n" , |
114 | __func__, dev_num, slave->prop.wake_capable); |
115 | return; |
116 | } |
117 | |
118 | if (sdw->link_res->hw_ops->program_sdi && wake_capable) |
119 | sdw->link_res->hw_ops->program_sdi(sdw, dev_num); |
120 | } |
121 | |
122 | static int sdw_master_read_intel_prop(struct sdw_bus *bus) |
123 | { |
124 | struct sdw_master_prop *prop = &bus->prop; |
125 | struct fwnode_handle *link; |
126 | char name[32]; |
127 | u32 quirk_mask; |
128 | |
129 | /* Find master handle */ |
130 | snprintf(buf: name, size: sizeof(name), |
131 | fmt: "mipi-sdw-link-%d-subproperties" , bus->link_id); |
132 | |
133 | link = device_get_named_child_node(dev: bus->dev, childname: name); |
134 | if (!link) { |
135 | dev_err(bus->dev, "Master node %s not found\n" , name); |
136 | return -EIO; |
137 | } |
138 | |
139 | fwnode_property_read_u32(fwnode: link, |
140 | propname: "intel-sdw-ip-clock" , |
141 | val: &prop->mclk_freq); |
142 | |
143 | /* the values reported by BIOS are the 2x clock, not the bus clock */ |
144 | prop->mclk_freq /= 2; |
145 | |
146 | fwnode_property_read_u32(fwnode: link, |
147 | propname: "intel-quirk-mask" , |
148 | val: &quirk_mask); |
149 | |
150 | if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE) |
151 | prop->hw_disabled = true; |
152 | |
153 | prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | |
154 | SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; |
155 | |
156 | return 0; |
157 | } |
158 | |
159 | static int intel_prop_read(struct sdw_bus *bus) |
160 | { |
161 | /* Initialize with default handler to read all DisCo properties */ |
162 | sdw_master_read_prop(bus); |
163 | |
164 | /* read Intel-specific properties */ |
165 | sdw_master_read_intel_prop(bus); |
166 | |
167 | return 0; |
168 | } |
169 | |
170 | static DEFINE_IDA(intel_peripheral_ida); |
171 | |
172 | static int intel_get_device_num_ida(struct sdw_bus *bus, struct sdw_slave *slave) |
173 | { |
174 | int bit; |
175 | |
176 | if (slave->prop.wake_capable || is_wake_capable(slave)) |
177 | return ida_alloc_range(&intel_peripheral_ida, |
178 | SDW_INTEL_DEV_NUM_IDA_MIN, SDW_MAX_DEVICES, |
179 | GFP_KERNEL); |
180 | |
181 | bit = find_first_zero_bit(addr: slave->bus->assigned, SDW_MAX_DEVICES); |
182 | if (bit == SDW_MAX_DEVICES) |
183 | return -ENODEV; |
184 | |
185 | return bit; |
186 | } |
187 | |
188 | static void intel_put_device_num_ida(struct sdw_bus *bus, struct sdw_slave *slave) |
189 | { |
190 | if (slave->prop.wake_capable || is_wake_capable(slave)) |
191 | ida_free(&intel_peripheral_ida, id: slave->dev_num); |
192 | } |
193 | |
194 | static struct sdw_master_ops sdw_intel_ops = { |
195 | .read_prop = intel_prop_read, |
196 | .override_adr = sdw_dmi_override_adr, |
197 | .xfer_msg = cdns_xfer_msg, |
198 | .xfer_msg_defer = cdns_xfer_msg_defer, |
199 | .set_bus_conf = cdns_bus_conf, |
200 | .pre_bank_switch = generic_pre_bank_switch, |
201 | .post_bank_switch = generic_post_bank_switch, |
202 | .read_ping_status = cdns_read_ping_status, |
203 | .get_device_num = intel_get_device_num_ida, |
204 | .put_device_num = intel_put_device_num_ida, |
205 | .new_peripheral_assigned = generic_new_peripheral_assigned, |
206 | }; |
207 | |
208 | /* |
209 | * probe and init (aux_dev_id argument is required by function prototype but not used) |
210 | */ |
211 | static int intel_link_probe(struct auxiliary_device *auxdev, |
212 | const struct auxiliary_device_id *aux_dev_id) |
213 | |
214 | { |
215 | struct device *dev = &auxdev->dev; |
216 | struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev); |
217 | struct sdw_intel *sdw; |
218 | struct sdw_cdns *cdns; |
219 | struct sdw_bus *bus; |
220 | int ret; |
221 | |
222 | sdw = devm_kzalloc(dev, size: sizeof(*sdw), GFP_KERNEL); |
223 | if (!sdw) |
224 | return -ENOMEM; |
225 | |
226 | cdns = &sdw->cdns; |
227 | bus = &cdns->bus; |
228 | |
229 | sdw->instance = auxdev->id; |
230 | sdw->link_res = &ldev->link_res; |
231 | cdns->dev = dev; |
232 | cdns->registers = sdw->link_res->registers; |
233 | cdns->ip_offset = sdw->link_res->ip_offset; |
234 | cdns->instance = sdw->instance; |
235 | cdns->msg_count = 0; |
236 | |
237 | /* single controller for all SoundWire links */ |
238 | bus->controller_id = 0; |
239 | |
240 | bus->link_id = auxdev->id; |
241 | bus->clk_stop_timeout = 1; |
242 | |
243 | sdw_cdns_probe(cdns); |
244 | |
245 | /* Set ops */ |
246 | bus->ops = &sdw_intel_ops; |
247 | |
248 | /* set driver data, accessed by snd_soc_dai_get_drvdata() */ |
249 | auxiliary_set_drvdata(auxdev, data: cdns); |
250 | |
251 | /* use generic bandwidth allocation algorithm */ |
252 | sdw->cdns.bus.compute_params = sdw_compute_params; |
253 | |
254 | /* avoid resuming from pm_runtime suspend if it's not required */ |
255 | dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND); |
256 | |
257 | ret = sdw_bus_master_add(bus, parent: dev, fwnode: dev->fwnode); |
258 | if (ret) { |
259 | dev_err(dev, "sdw_bus_master_add fail: %d\n" , ret); |
260 | return ret; |
261 | } |
262 | |
263 | if (bus->prop.hw_disabled) |
264 | dev_info(dev, |
265 | "SoundWire master %d is disabled, will be ignored\n" , |
266 | bus->link_id); |
267 | /* |
268 | * Ignore BIOS err_threshold, it's a really bad idea when dealing |
269 | * with multiple hardware synchronized links |
270 | */ |
271 | bus->prop.err_threshold = 0; |
272 | |
273 | return 0; |
274 | } |
275 | |
276 | int intel_link_startup(struct auxiliary_device *auxdev) |
277 | { |
278 | struct device *dev = &auxdev->dev; |
279 | struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); |
280 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
281 | struct sdw_bus *bus = &cdns->bus; |
282 | int link_flags; |
283 | bool multi_link; |
284 | u32 clock_stop_quirks; |
285 | int ret; |
286 | |
287 | if (bus->prop.hw_disabled) { |
288 | dev_info(dev, |
289 | "SoundWire master %d is disabled, ignoring\n" , |
290 | sdw->instance); |
291 | return 0; |
292 | } |
293 | |
294 | link_flags = md_flags >> (bus->link_id * 8); |
295 | multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK); |
296 | if (!multi_link) { |
297 | dev_dbg(dev, "Multi-link is disabled\n" ); |
298 | } else { |
299 | /* |
300 | * hardware-based synchronization is required regardless |
301 | * of the number of segments used by a stream: SSP-based |
302 | * synchronization is gated by gsync when the multi-master |
303 | * mode is set. |
304 | */ |
305 | bus->hw_sync_min_links = 1; |
306 | } |
307 | bus->multi_link = multi_link; |
308 | |
309 | /* Initialize shim, controller */ |
310 | ret = sdw_intel_link_power_up(sdw); |
311 | if (ret) |
312 | goto err_init; |
313 | |
314 | /* Register DAIs */ |
315 | ret = sdw_intel_register_dai(sdw); |
316 | if (ret) { |
317 | dev_err(dev, "DAI registration failed: %d\n" , ret); |
318 | goto err_power_up; |
319 | } |
320 | |
321 | sdw_intel_debugfs_init(sdw); |
322 | |
323 | /* Enable runtime PM */ |
324 | if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) { |
325 | pm_runtime_set_autosuspend_delay(dev, |
326 | INTEL_MASTER_SUSPEND_DELAY_MS); |
327 | pm_runtime_use_autosuspend(dev); |
328 | pm_runtime_mark_last_busy(dev); |
329 | |
330 | pm_runtime_set_active(dev); |
331 | pm_runtime_enable(dev); |
332 | |
333 | pm_runtime_resume(dev: bus->dev); |
334 | } |
335 | |
336 | /* start bus */ |
337 | ret = sdw_intel_start_bus(sdw); |
338 | if (ret) { |
339 | dev_err(dev, "bus start failed: %d\n" , ret); |
340 | goto err_pm_runtime; |
341 | } |
342 | |
343 | clock_stop_quirks = sdw->link_res->clock_stop_quirks; |
344 | if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) { |
345 | /* |
346 | * To keep the clock running we need to prevent |
347 | * pm_runtime suspend from happening by increasing the |
348 | * reference count. |
349 | * This quirk is specified by the parent PCI device in |
350 | * case of specific latency requirements. It will have |
351 | * no effect if pm_runtime is disabled by the user via |
352 | * a module parameter for testing purposes. |
353 | */ |
354 | pm_runtime_get_noresume(dev); |
355 | } |
356 | |
357 | /* |
358 | * The runtime PM status of Slave devices is "Unsupported" |
359 | * until they report as ATTACHED. If they don't, e.g. because |
360 | * there are no Slave devices populated or if the power-on is |
361 | * delayed or dependent on a power switch, the Master will |
362 | * remain active and prevent its parent from suspending. |
363 | * |
364 | * Conditionally force the pm_runtime core to re-evaluate the |
365 | * Master status in the absence of any Slave activity. A quirk |
366 | * is provided to e.g. deal with Slaves that may be powered on |
367 | * with a delay. A more complete solution would require the |
368 | * definition of Master properties. |
369 | */ |
370 | if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) { |
371 | pm_runtime_mark_last_busy(dev: bus->dev); |
372 | pm_runtime_mark_last_busy(dev); |
373 | pm_runtime_idle(dev); |
374 | } |
375 | |
376 | sdw->startup_done = true; |
377 | return 0; |
378 | |
379 | err_pm_runtime: |
380 | if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) |
381 | pm_runtime_disable(dev); |
382 | err_power_up: |
383 | sdw_intel_link_power_down(sdw); |
384 | err_init: |
385 | return ret; |
386 | } |
387 | |
388 | static void intel_link_remove(struct auxiliary_device *auxdev) |
389 | { |
390 | struct sdw_cdns *cdns = auxiliary_get_drvdata(auxdev); |
391 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
392 | struct sdw_bus *bus = &cdns->bus; |
393 | |
394 | /* |
395 | * Since pm_runtime is already disabled, we don't decrease |
396 | * the refcount when the clock_stop_quirk is |
397 | * SDW_INTEL_CLK_STOP_NOT_ALLOWED |
398 | */ |
399 | if (!bus->prop.hw_disabled) { |
400 | sdw_intel_debugfs_exit(sdw); |
401 | sdw_cdns_enable_interrupt(cdns, state: false); |
402 | } |
403 | sdw_bus_master_delete(bus); |
404 | } |
405 | |
406 | int intel_link_process_wakeen_event(struct auxiliary_device *auxdev) |
407 | { |
408 | struct device *dev = &auxdev->dev; |
409 | struct sdw_intel *sdw; |
410 | struct sdw_bus *bus; |
411 | |
412 | sdw = auxiliary_get_drvdata(auxdev); |
413 | bus = &sdw->cdns.bus; |
414 | |
415 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
416 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
417 | bus->link_id); |
418 | return 0; |
419 | } |
420 | |
421 | if (!sdw_intel_shim_check_wake(sdw)) |
422 | return 0; |
423 | |
424 | /* disable WAKEEN interrupt ASAP to prevent interrupt flood */ |
425 | sdw_intel_shim_wake(sdw, wake_enable: false); |
426 | |
427 | /* |
428 | * resume the Master, which will generate a bus reset and result in |
429 | * Slaves re-attaching and be re-enumerated. The SoundWire physical |
430 | * device which generated the wake will trigger an interrupt, which |
431 | * will in turn cause the corresponding Linux Slave device to be |
432 | * resumed and the Slave codec driver to check the status. |
433 | */ |
434 | pm_request_resume(dev); |
435 | |
436 | return 0; |
437 | } |
438 | |
439 | /* |
440 | * PM calls |
441 | */ |
442 | |
443 | static int intel_resume_child_device(struct device *dev, void *data) |
444 | { |
445 | int ret; |
446 | struct sdw_slave *slave = dev_to_sdw_dev(dev); |
447 | |
448 | if (!slave->probed) { |
449 | dev_dbg(dev, "skipping device, no probed driver\n" ); |
450 | return 0; |
451 | } |
452 | if (!slave->dev_num_sticky) { |
453 | dev_dbg(dev, "skipping device, never detected on bus\n" ); |
454 | return 0; |
455 | } |
456 | |
457 | ret = pm_request_resume(dev); |
458 | if (ret < 0) { |
459 | dev_err(dev, "%s: pm_request_resume failed: %d\n" , __func__, ret); |
460 | return ret; |
461 | } |
462 | |
463 | return 0; |
464 | } |
465 | |
466 | static int __maybe_unused intel_pm_prepare(struct device *dev) |
467 | { |
468 | struct sdw_cdns *cdns = dev_get_drvdata(dev); |
469 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
470 | struct sdw_bus *bus = &cdns->bus; |
471 | u32 clock_stop_quirks; |
472 | int ret; |
473 | |
474 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
475 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
476 | bus->link_id); |
477 | return 0; |
478 | } |
479 | |
480 | clock_stop_quirks = sdw->link_res->clock_stop_quirks; |
481 | |
482 | if (pm_runtime_suspended(dev) && |
483 | pm_runtime_suspended(dev: dev->parent) && |
484 | ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || |
485 | !clock_stop_quirks)) { |
486 | /* |
487 | * if we've enabled clock stop, and the parent is suspended, the SHIM registers |
488 | * are not accessible and the shim wake cannot be disabled. |
489 | * The only solution is to resume the entire bus to full power |
490 | */ |
491 | |
492 | /* |
493 | * If any operation in this block fails, we keep going since we don't want |
494 | * to prevent system suspend from happening and errors should be recoverable |
495 | * on resume. |
496 | */ |
497 | |
498 | /* |
499 | * first resume the device for this link. This will also by construction |
500 | * resume the PCI parent device. |
501 | */ |
502 | ret = pm_request_resume(dev); |
503 | if (ret < 0) { |
504 | dev_err(dev, "%s: pm_request_resume failed: %d\n" , __func__, ret); |
505 | return 0; |
506 | } |
507 | |
508 | /* |
509 | * Continue resuming the entire bus (parent + child devices) to exit |
510 | * the clock stop mode. If there are no devices connected on this link |
511 | * this is a no-op. |
512 | * The resume to full power could have been implemented with a .prepare |
513 | * step in SoundWire codec drivers. This would however require a lot |
514 | * of code to handle an Intel-specific corner case. It is simpler in |
515 | * practice to add a loop at the link level. |
516 | */ |
517 | ret = device_for_each_child(dev: bus->dev, NULL, fn: intel_resume_child_device); |
518 | |
519 | if (ret < 0) |
520 | dev_err(dev, "%s: intel_resume_child_device failed: %d\n" , __func__, ret); |
521 | } |
522 | |
523 | return 0; |
524 | } |
525 | |
526 | static int __maybe_unused intel_suspend(struct device *dev) |
527 | { |
528 | struct sdw_cdns *cdns = dev_get_drvdata(dev); |
529 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
530 | struct sdw_bus *bus = &cdns->bus; |
531 | u32 clock_stop_quirks; |
532 | int ret; |
533 | |
534 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
535 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
536 | bus->link_id); |
537 | return 0; |
538 | } |
539 | |
540 | if (pm_runtime_suspended(dev)) { |
541 | dev_dbg(dev, "pm_runtime status: suspended\n" ); |
542 | |
543 | clock_stop_quirks = sdw->link_res->clock_stop_quirks; |
544 | |
545 | if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) || |
546 | !clock_stop_quirks) { |
547 | |
548 | if (pm_runtime_suspended(dev: dev->parent)) { |
549 | /* |
550 | * paranoia check: this should not happen with the .prepare |
551 | * resume to full power |
552 | */ |
553 | dev_err(dev, "%s: invalid config: parent is suspended\n" , __func__); |
554 | } else { |
555 | sdw_intel_shim_wake(sdw, wake_enable: false); |
556 | } |
557 | } |
558 | |
559 | return 0; |
560 | } |
561 | |
562 | ret = sdw_intel_stop_bus(sdw, clock_stop: false); |
563 | if (ret < 0) { |
564 | dev_err(dev, "%s: cannot stop bus: %d\n" , __func__, ret); |
565 | return ret; |
566 | } |
567 | |
568 | return 0; |
569 | } |
570 | |
571 | static int __maybe_unused intel_suspend_runtime(struct device *dev) |
572 | { |
573 | struct sdw_cdns *cdns = dev_get_drvdata(dev); |
574 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
575 | struct sdw_bus *bus = &cdns->bus; |
576 | u32 clock_stop_quirks; |
577 | int ret; |
578 | |
579 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
580 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
581 | bus->link_id); |
582 | return 0; |
583 | } |
584 | |
585 | clock_stop_quirks = sdw->link_res->clock_stop_quirks; |
586 | |
587 | if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { |
588 | ret = sdw_intel_stop_bus(sdw, clock_stop: false); |
589 | if (ret < 0) { |
590 | dev_err(dev, "%s: cannot stop bus during teardown: %d\n" , |
591 | __func__, ret); |
592 | return ret; |
593 | } |
594 | } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET || !clock_stop_quirks) { |
595 | ret = sdw_intel_stop_bus(sdw, clock_stop: true); |
596 | if (ret < 0) { |
597 | dev_err(dev, "%s: cannot stop bus during clock_stop: %d\n" , |
598 | __func__, ret); |
599 | return ret; |
600 | } |
601 | } else { |
602 | dev_err(dev, "%s clock_stop_quirks %x unsupported\n" , |
603 | __func__, clock_stop_quirks); |
604 | ret = -EINVAL; |
605 | } |
606 | |
607 | return ret; |
608 | } |
609 | |
610 | static int __maybe_unused intel_resume(struct device *dev) |
611 | { |
612 | struct sdw_cdns *cdns = dev_get_drvdata(dev); |
613 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
614 | struct sdw_bus *bus = &cdns->bus; |
615 | int link_flags; |
616 | int ret; |
617 | |
618 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
619 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
620 | bus->link_id); |
621 | return 0; |
622 | } |
623 | |
624 | if (pm_runtime_suspended(dev)) { |
625 | dev_dbg(dev, "pm_runtime status was suspended, forcing active\n" ); |
626 | |
627 | /* follow required sequence from runtime_pm.rst */ |
628 | pm_runtime_disable(dev); |
629 | pm_runtime_set_active(dev); |
630 | pm_runtime_mark_last_busy(dev); |
631 | pm_runtime_enable(dev); |
632 | |
633 | pm_runtime_resume(dev: bus->dev); |
634 | |
635 | link_flags = md_flags >> (bus->link_id * 8); |
636 | |
637 | if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE)) |
638 | pm_runtime_idle(dev); |
639 | } |
640 | |
641 | ret = sdw_intel_link_power_up(sdw); |
642 | if (ret) { |
643 | dev_err(dev, "%s failed: %d\n" , __func__, ret); |
644 | return ret; |
645 | } |
646 | |
647 | /* |
648 | * make sure all Slaves are tagged as UNATTACHED and provide |
649 | * reason for reinitialization |
650 | */ |
651 | sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); |
652 | |
653 | ret = sdw_intel_start_bus(sdw); |
654 | if (ret < 0) { |
655 | dev_err(dev, "cannot start bus during resume\n" ); |
656 | sdw_intel_link_power_down(sdw); |
657 | return ret; |
658 | } |
659 | |
660 | /* |
661 | * after system resume, the pm_runtime suspend() may kick in |
662 | * during the enumeration, before any children device force the |
663 | * master device to remain active. Using pm_runtime_get() |
664 | * routines is not really possible, since it'd prevent the |
665 | * master from suspending. |
666 | * A reasonable compromise is to update the pm_runtime |
667 | * counters and delay the pm_runtime suspend by several |
668 | * seconds, by when all enumeration should be complete. |
669 | */ |
670 | pm_runtime_mark_last_busy(dev: bus->dev); |
671 | pm_runtime_mark_last_busy(dev); |
672 | |
673 | return 0; |
674 | } |
675 | |
676 | static int __maybe_unused intel_resume_runtime(struct device *dev) |
677 | { |
678 | struct sdw_cdns *cdns = dev_get_drvdata(dev); |
679 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
680 | struct sdw_bus *bus = &cdns->bus; |
681 | u32 clock_stop_quirks; |
682 | int ret; |
683 | |
684 | if (bus->prop.hw_disabled || !sdw->startup_done) { |
685 | dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n" , |
686 | bus->link_id); |
687 | return 0; |
688 | } |
689 | |
690 | /* unconditionally disable WAKEEN interrupt */ |
691 | sdw_intel_shim_wake(sdw, wake_enable: false); |
692 | |
693 | clock_stop_quirks = sdw->link_res->clock_stop_quirks; |
694 | |
695 | if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) { |
696 | ret = sdw_intel_link_power_up(sdw); |
697 | if (ret) { |
698 | dev_err(dev, "%s: power_up failed after teardown: %d\n" , __func__, ret); |
699 | return ret; |
700 | } |
701 | |
702 | /* |
703 | * make sure all Slaves are tagged as UNATTACHED and provide |
704 | * reason for reinitialization |
705 | */ |
706 | sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); |
707 | |
708 | ret = sdw_intel_start_bus(sdw); |
709 | if (ret < 0) { |
710 | dev_err(dev, "%s: cannot start bus after teardown: %d\n" , __func__, ret); |
711 | sdw_intel_link_power_down(sdw); |
712 | return ret; |
713 | } |
714 | |
715 | } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) { |
716 | ret = sdw_intel_link_power_up(sdw); |
717 | if (ret) { |
718 | dev_err(dev, "%s: power_up failed after bus reset: %d\n" , __func__, ret); |
719 | return ret; |
720 | } |
721 | |
722 | ret = sdw_intel_start_bus_after_reset(sdw); |
723 | if (ret < 0) { |
724 | dev_err(dev, "%s: cannot start bus after reset: %d\n" , __func__, ret); |
725 | sdw_intel_link_power_down(sdw); |
726 | return ret; |
727 | } |
728 | } else if (!clock_stop_quirks) { |
729 | |
730 | sdw_intel_check_clock_stop(sdw); |
731 | |
732 | ret = sdw_intel_link_power_up(sdw); |
733 | if (ret) { |
734 | dev_err(dev, "%s: power_up failed: %d\n" , __func__, ret); |
735 | return ret; |
736 | } |
737 | |
738 | ret = sdw_intel_start_bus_after_clock_stop(sdw); |
739 | if (ret < 0) { |
740 | dev_err(dev, "%s: cannot start bus after clock stop: %d\n" , __func__, ret); |
741 | sdw_intel_link_power_down(sdw); |
742 | return ret; |
743 | } |
744 | } else { |
745 | dev_err(dev, "%s: clock_stop_quirks %x unsupported\n" , |
746 | __func__, clock_stop_quirks); |
747 | ret = -EINVAL; |
748 | } |
749 | |
750 | return ret; |
751 | } |
752 | |
753 | static const struct dev_pm_ops intel_pm = { |
754 | .prepare = intel_pm_prepare, |
755 | SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume) |
756 | SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL) |
757 | }; |
758 | |
759 | static const struct auxiliary_device_id intel_link_id_table[] = { |
760 | { .name = "soundwire_intel.link" }, |
761 | {}, |
762 | }; |
763 | MODULE_DEVICE_TABLE(auxiliary, intel_link_id_table); |
764 | |
765 | static struct auxiliary_driver sdw_intel_drv = { |
766 | .probe = intel_link_probe, |
767 | .remove = intel_link_remove, |
768 | .driver = { |
769 | /* auxiliary_driver_register() sets .name to be the modname */ |
770 | .pm = &intel_pm, |
771 | }, |
772 | .id_table = intel_link_id_table |
773 | }; |
774 | module_auxiliary_driver(sdw_intel_drv); |
775 | |
776 | MODULE_LICENSE("Dual BSD/GPL" ); |
777 | MODULE_DESCRIPTION("Intel Soundwire Link Driver" ); |
778 | |