summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/soundwire/Kconfig1
-rw-r--r--drivers/soundwire/amd_init.c12
-rw-r--r--drivers/soundwire/intel_ace2x.c7
-rw-r--r--drivers/soundwire/intel_init.c13
-rw-r--r--drivers/soundwire/slave.c14
5 files changed, 34 insertions, 13 deletions
diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig
index 4d8f3b7024ae..f66f869dff2e 100644
--- a/drivers/soundwire/Kconfig
+++ b/drivers/soundwire/Kconfig
@@ -6,6 +6,7 @@
menuconfig SOUNDWIRE
tristate "SoundWire support"
depends on ACPI || OF
+ depends on SND_SOC_SDCA_OPTIONAL
help
SoundWire is a 2-Pin interface with data and clock line ratified
by the MIPI Alliance. SoundWire is used for transporting data
diff --git a/drivers/soundwire/amd_init.c b/drivers/soundwire/amd_init.c
index db040f435059..53d1d707ca1a 100644
--- a/drivers/soundwire/amd_init.c
+++ b/drivers/soundwire/amd_init.c
@@ -177,7 +177,7 @@ EXPORT_SYMBOL_NS(sdw_amd_probe, SOUNDWIRE_AMD_INIT);
void sdw_amd_exit(struct sdw_amd_ctx *ctx)
{
sdw_amd_cleanup(ctx);
- kfree(ctx->ids);
+ kfree(ctx->peripherals);
kfree(ctx);
}
EXPORT_SYMBOL_NS(sdw_amd_exit, SOUNDWIRE_AMD_INIT);
@@ -204,10 +204,11 @@ int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx)
num_slaves++;
}
- ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
- if (!ctx->ids)
+ ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves),
+ GFP_KERNEL);
+ if (!ctx->peripherals)
return -ENOMEM;
- ctx->num_slaves = num_slaves;
+ ctx->peripherals->num_peripherals = num_slaves;
for (index = 0; index < ctx->count; index++) {
if (!(ctx->link_mask & BIT(index)))
continue;
@@ -215,8 +216,7 @@ int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx)
if (amd_manager) {
bus = &amd_manager->bus;
list_for_each_entry(slave, &bus->slaves, node) {
- ctx->ids[i].id = slave->id;
- ctx->ids[i].link_id = bus->link_id;
+ ctx->peripherals->array[i] = slave;
i++;
}
}
diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c
index 4f3dd70d6a1a..a005b63582e9 100644
--- a/drivers/soundwire/intel_ace2x.c
+++ b/drivers/soundwire/intel_ace2x.c
@@ -175,6 +175,9 @@ static int intel_link_power_up(struct sdw_intel *sdw)
__func__, ret);
goto out;
}
+
+ hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true,
+ AZX_REG_ML_LEPTR_ID_SDW, true);
}
*shim_mask |= BIT(link_id);
@@ -201,6 +204,10 @@ static int intel_link_power_down(struct sdw_intel *sdw)
*shim_mask &= ~BIT(link_id);
+ if (!*shim_mask)
+ hdac_bus_eml_enable_interrupt_unlocked(sdw->link_res->hbus, true,
+ AZX_REG_ML_LEPTR_ID_SDW, false);
+
ret = hdac_bus_eml_sdw_power_down_unlocked(sdw->link_res->hbus, link_id);
if (ret < 0) {
dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_power_down failed: %d\n",
diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
index a09134b97cd6..12e7a98f319f 100644
--- a/drivers/soundwire/intel_init.c
+++ b/drivers/soundwire/intel_init.c
@@ -252,17 +252,16 @@ static struct sdw_intel_ctx
num_slaves++;
}
- ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
- if (!ctx->ids)
+ ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves),
+ GFP_KERNEL);
+ if (!ctx->peripherals)
goto err;
-
- ctx->num_slaves = num_slaves;
+ ctx->peripherals->num_peripherals = num_slaves;
i = 0;
list_for_each_entry(link, &ctx->link_list, list) {
bus = &link->cdns->bus;
list_for_each_entry(slave, &bus->slaves, node) {
- ctx->ids[i].id = slave->id;
- ctx->ids[i].link_id = bus->link_id;
+ ctx->peripherals->array[i] = slave;
i++;
}
}
@@ -371,7 +370,7 @@ void sdw_intel_exit(struct sdw_intel_ctx *ctx)
}
sdw_intel_cleanup(ctx);
- kfree(ctx->ids);
+ kfree(ctx->peripherals);
kfree(ctx->ldev);
kfree(ctx);
}
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
index f1a4df6cfebd..97cf8bcca047 100644
--- a/drivers/soundwire/slave.c
+++ b/drivers/soundwire/slave.c
@@ -5,6 +5,7 @@
#include <linux/of.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
+#include <sound/sdca.h>
#include "bus.h"
#include "sysfs_local.h"
@@ -70,6 +71,17 @@ int sdw_slave_add(struct sdw_bus *bus,
list_add_tail(&slave->node, &bus->slaves);
mutex_unlock(&bus->bus_lock);
+ /*
+ * The Soundwire driver probe may optionally register SDCA
+ * sub-devices, one per Function. This means the information
+ * on the SDCA revision and the number/type of Functions need
+ * to be extracted from platform firmware before the SoundWire
+ * driver probe, and as a consequence before the SoundWire
+ * device_register() below.
+ */
+ sdca_lookup_interface_revision(slave);
+ sdca_lookup_functions(slave);
+
ret = device_register(&slave->dev);
if (ret) {
dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
@@ -259,3 +271,5 @@ int sdw_of_find_slaves(struct sdw_bus *bus)
return 0;
}
+
+MODULE_IMPORT_NS(SND_SOC_SDCA);