summaryrefslogtreecommitdiff
path: root/drivers/soundwire/intel_bus_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soundwire/intel_bus_common.c')
-rw-r--r--drivers/soundwire/intel_bus_common.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/soundwire/intel_bus_common.c b/drivers/soundwire/intel_bus_common.c
index e5ac3cc7cb79..ad1f8ebdbfc9 100644
--- a/drivers/soundwire/intel_bus_common.c
+++ b/drivers/soundwire/intel_bus_common.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
-// Copyright(c) 2015-2023 Intel Corporation. All rights reserved.
+// Copyright(c) 2015-2023 Intel Corporation
#include <linux/acpi.h>
#include <linux/soundwire/sdw_registers.h>
@@ -16,6 +16,12 @@ int intel_start_bus(struct sdw_intel *sdw)
struct sdw_bus *bus = &cdns->bus;
int ret;
+ ret = sdw_cdns_soft_reset(cdns);
+ if (ret < 0) {
+ dev_err(dev, "%s: unable to soft-reset Cadence IP: %d\n", __func__, ret);
+ return ret;
+ }
+
/*
* follow recommended programming flows to avoid timeouts when
* gsync is enabled
@@ -45,21 +51,24 @@ int intel_start_bus(struct sdw_intel *sdw)
return ret;
}
- ret = sdw_cdns_exit_reset(cdns);
+ ret = sdw_cdns_enable_interrupt(cdns, true);
if (ret < 0) {
- dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
+ dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
return ret;
}
- ret = sdw_cdns_enable_interrupt(cdns, true);
+ ret = sdw_cdns_exit_reset(cdns);
if (ret < 0) {
- dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
+ dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
return ret;
}
sdw_cdns_check_self_clearing_bits(cdns, __func__,
true, INTEL_MASTER_RESET_ITERATIONS);
+ schedule_delayed_work(&cdns->attach_dwork,
+ msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
+
return 0;
}
@@ -136,21 +145,24 @@ int intel_start_bus_after_reset(struct sdw_intel *sdw)
return ret;
}
- ret = sdw_cdns_exit_reset(cdns);
+ ret = sdw_cdns_enable_interrupt(cdns, true);
if (ret < 0) {
- dev_err(dev, "unable to exit bus reset sequence during resume\n");
+ dev_err(dev, "cannot enable interrupts during resume\n");
return ret;
}
- ret = sdw_cdns_enable_interrupt(cdns, true);
+ ret = sdw_cdns_exit_reset(cdns);
if (ret < 0) {
- dev_err(dev, "cannot enable interrupts during resume\n");
+ dev_err(dev, "unable to exit bus reset sequence during resume\n");
return ret;
}
}
sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
+ schedule_delayed_work(&cdns->attach_dwork,
+ msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
+
return 0;
}
@@ -184,6 +196,9 @@ int intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
+ schedule_delayed_work(&cdns->attach_dwork,
+ msecs_to_jiffies(SDW_INTEL_DELAYED_ENUMERATION_MS));
+
return 0;
}
@@ -194,6 +209,8 @@ int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
bool wake_enable = false;
int ret;
+ cancel_delayed_work_sync(&cdns->attach_dwork);
+
if (clock_stop) {
ret = sdw_cdns_clock_stop(cdns, true);
if (ret < 0)