Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions include/sound/soc-component.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ struct snd_soc_component {
int (*init)(struct snd_soc_component *component);

/* function mark */
struct snd_pcm_substream *mark_module;
void *mark_module;
struct snd_pcm_substream *mark_open;
struct snd_pcm_substream *mark_hw_params;
struct snd_pcm_substream *mark_trigger;
Expand Down Expand Up @@ -391,15 +391,13 @@ void snd_soc_component_exit_regmap(struct snd_soc_component *component);
#define snd_soc_component_module_get_when_open(component, substream) \
snd_soc_component_module_get(component, substream, 1)
int snd_soc_component_module_get(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open);
void *mark, int upon_open);
#define snd_soc_component_module_put_when_remove(component) \
snd_soc_component_module_put(component, NULL, 0, 0)
#define snd_soc_component_module_put_when_close(component, substream, rollback) \
snd_soc_component_module_put(component, substream, 1, rollback)
void snd_soc_component_module_put(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open, int rollback);
void *mark, int upon_open, int rollback);

static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
void *data)
Expand Down Expand Up @@ -455,8 +453,10 @@ int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
const struct of_phandle_args *args,
const char **dai_name);
int snd_soc_component_compr_open(struct snd_compr_stream *cstream);
void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
int snd_soc_component_compr_open(struct snd_soc_component *component,
struct snd_compr_stream *cstream);
void snd_soc_component_compr_free(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
int rollback);
int snd_soc_component_compr_trigger(struct snd_compr_stream *cstream, int cmd);
int snd_soc_component_compr_set_params(struct snd_compr_stream *cstream,
Expand Down
22 changes: 22 additions & 0 deletions include/sound/sof.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@

struct snd_sof_dsp_ops;

/**
* enum snd_sof_fw_state - DSP firmware state definitions
* @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started
* @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple)
* @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress
* @SOF_FW_BOOT_FAILED: firmware boot failed
* @SOF_FW_BOOT_READY_FAILED: firmware booted but fw_ready op failed
* @SOF_FW_BOOT_READY_OK: firmware booted and fw_ready op is OK
* @SOF_FW_BOOT_COMPLETE: firmware is booted up and functional
* @SOF_FW_CRASHED: firmware crashed after successful boot
*/
enum snd_sof_fw_state {
SOF_FW_BOOT_NOT_STARTED = 0,
SOF_FW_BOOT_PREPARE,
SOF_FW_BOOT_IN_PROGRESS,
SOF_FW_BOOT_FAILED,
SOF_FW_BOOT_READY_FAILED,
SOF_FW_BOOT_READY_OK,
SOF_FW_BOOT_COMPLETE,
SOF_FW_CRASHED,
};

/*
* SOF Platform data.
*/
Expand Down
61 changes: 26 additions & 35 deletions sound/soc/soc-component.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,34 +251,32 @@ int snd_soc_component_set_jack(struct snd_soc_component *component,
EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);

int snd_soc_component_module_get(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open)
void *mark, int upon_open)
{
int ret = 0;

if (component->driver->module_get_upon_open == !!upon_open &&
!try_module_get(component->dev->driver->owner))
ret = -ENODEV;

/* mark substream if succeeded */
/* mark module if succeeded */
if (ret == 0)
soc_component_mark_push(component, substream, module);
soc_component_mark_push(component, mark, module);

return soc_component_ret(component, ret);
}

void snd_soc_component_module_put(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open, int rollback)
void *mark, int upon_open, int rollback)
{
if (rollback && !soc_component_mark_match(component, substream, module))
if (rollback && !soc_component_mark_match(component, mark, module))
return;

if (component->driver->module_get_upon_open == !!upon_open)
module_put(component->dev->driver->owner);

/* remove marked substream */
soc_component_mark_pop(component, substream, module);
/* remove the mark from module */
soc_component_mark_pop(component, mark, module);
}

int snd_soc_component_open(struct snd_soc_component *component,
Expand Down Expand Up @@ -425,43 +423,36 @@ EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);

#endif

int snd_soc_component_compr_open(struct snd_compr_stream *cstream)
int snd_soc_component_compr_open(struct snd_soc_component *component,
struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
int i, ret;
int ret = 0;

for_each_rtd_components(rtd, i, component) {
if (component->driver->compress_ops &&
component->driver->compress_ops->open) {
ret = component->driver->compress_ops->open(component, cstream);
if (ret < 0)
return soc_component_ret(component, ret);
}
if (component->driver->compress_ops &&
component->driver->compress_ops->open)
ret = component->driver->compress_ops->open(component, cstream);

/* mark substream if succeeded */
if (ret == 0)
soc_component_mark_push(component, cstream, compr_open);
}

return 0;
return soc_component_ret(component, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_open);

void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
void snd_soc_component_compr_free(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
int rollback)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
int i;
if (rollback && !soc_component_mark_match(component, cstream, compr_open))
return;

for_each_rtd_components(rtd, i, component) {
if (rollback && !soc_component_mark_match(component, cstream, compr_open))
continue;
if (component->driver->compress_ops &&
component->driver->compress_ops->free)
component->driver->compress_ops->free(component, cstream);

if (component->driver->compress_ops &&
component->driver->compress_ops->free)
component->driver->compress_ops->free(component, cstream);

soc_component_mark_pop(component, cstream, compr_open);
}
/* remove marked substream */
soc_component_mark_pop(component, cstream, compr_open);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_free);

Expand Down
43 changes: 38 additions & 5 deletions sound/soc/soc-compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,39 @@
#include <sound/soc-link.h>
#include <linux/pm_runtime.h>

static int snd_soc_compr_components_open(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
int ret = 0;
int i;

for_each_rtd_components(rtd, i, component) {
ret = snd_soc_component_module_get_when_open(component, cstream);
if (ret < 0)
break;

ret = snd_soc_component_compr_open(component, cstream);
if (ret < 0)
break;
}

return ret;
}

static void snd_soc_compr_components_free(struct snd_compr_stream *cstream,
int rollback)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_component *component;
int i;

for_each_rtd_components(rtd, i, component) {
snd_soc_component_compr_free(component, cstream, rollback);
snd_soc_component_module_put_when_close(component, cstream, rollback);
}
}

static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
Expand All @@ -44,7 +77,7 @@ static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback)

snd_soc_link_compr_shutdown(cstream, rollback);

snd_soc_component_compr_free(cstream, rollback);
snd_soc_compr_components_free(cstream, rollback);

snd_soc_dai_compr_shutdown(cpu_dai, cstream, rollback);

Expand Down Expand Up @@ -80,7 +113,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
if (ret < 0)
goto err;

ret = snd_soc_component_compr_open(cstream);
ret = snd_soc_compr_components_open(cstream);
if (ret < 0)
goto err;

Expand Down Expand Up @@ -137,7 +170,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
if (ret < 0)
goto out;

ret = snd_soc_component_compr_open(cstream);
ret = snd_soc_compr_components_open(cstream);
if (ret < 0)
goto open_err;

Expand All @@ -160,7 +193,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
return 0;

machine_err:
snd_soc_component_compr_free(cstream, 1);
snd_soc_compr_components_free(cstream, 1);
open_err:
snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1);
out:
Expand Down Expand Up @@ -205,7 +238,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)

snd_soc_link_compr_shutdown(cstream, 0);

snd_soc_component_compr_free(cstream, 0);
snd_soc_compr_components_free(cstream, 0);

snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0);

Expand Down
5 changes: 4 additions & 1 deletion sound/soc/sof/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)

snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
control.o trace.o utils.o sof-audio.o stream-ipc.o
control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o

snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o
Expand All @@ -12,9 +12,12 @@ snd-sof-of-objs := sof-of-dev.o

snd-sof-nocodec-objs := nocodec.o

snd-sof-utils-objs := sof-utils.o

obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o
obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o

obj-$(CONFIG_SND_SOC_SOF) += snd-sof-utils.o

obj-$(CONFIG_SND_SOC_SOF_ACPI_DEV) += snd-sof-acpi.o
obj-$(CONFIG_SND_SOC_SOF_OF) += snd-sof-of.o
Expand Down
22 changes: 11 additions & 11 deletions sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
return ret;
}

sdev->fw_state = SOF_FW_BOOT_PREPARE;
sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE);

/* check machine info */
ret = sof_machine_check(sdev);
Expand Down Expand Up @@ -189,7 +189,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
goto fw_load_err;
}

sdev->fw_state = SOF_FW_BOOT_IN_PROGRESS;
sof_set_fw_state(sdev, SOF_FW_BOOT_IN_PROGRESS);

/*
* Boot the firmware. The FW boot status will be modified
Expand Down Expand Up @@ -265,7 +265,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
snd_sof_remove(sdev);

/* all resources freed, update state to match */
sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);
sdev->first_boot = true;

return ret;
Expand Down Expand Up @@ -300,7 +300,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)

sdev->pdata = plat_data;
sdev->first_boot = true;
sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED);
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
#endif
Expand Down Expand Up @@ -362,6 +362,13 @@ int snd_sof_device_remove(struct device *dev)
if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
cancel_work_sync(&sdev->probe_work);

/*
* Unregister machine driver. This will unbind the snd_card which
* will remove the component driver and unload the topology
* before freeing the snd_card.
*/
snd_sof_machine_unregister(sdev, pdata);

if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
ret = snd_sof_dsp_power_down_notify(sdev);
if (ret < 0)
Expand All @@ -373,13 +380,6 @@ int snd_sof_device_remove(struct device *dev)
snd_sof_free_trace(sdev);
}

/*
* Unregister machine driver. This will unbind the snd_card which
* will remove the component driver and unload the topology
* before freeing the snd_card.
*/
snd_sof_machine_unregister(sdev, pdata);

/*
* Unregistering the machine driver results in unloading the topology.
* Some widgets, ex: scheduler, attempt to power down the core they are
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sof/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags)

if (sof_ops(sdev)->dbg_dump && !sdev->dbg_dump_printed) {
dev_err(sdev->dev, "------------[ DSP dump start ]------------\n");
dev_err(sdev->dev, "DSP firmware state: %d\n", sdev->fw_state);
sof_ops(sdev)->dbg_dump(sdev, flags);
dev_err(sdev->dev, "------------[ DSP dump end ]------------\n");
if (!print_all)
Expand Down Expand Up @@ -864,6 +865,7 @@ void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev)
/* dump vital information to the logs */
snd_sof_ipc_dump(sdev);
snd_sof_dsp_dbg_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX);
sof_set_fw_state(sdev, SOF_FW_CRASHED);
snd_sof_trace_notify_for_error(sdev);
}
EXPORT_SYMBOL(snd_sof_handle_fw_exception);
7 changes: 3 additions & 4 deletions sound/soc/sof/intel/hda-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@
#include "../ops.h"
#include "hda.h"

static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev)
static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_ext_stream *stream = hda->dtrace_stream;
struct hdac_stream *hstream = &stream->hstream;
struct snd_dma_buffer *dmab = &sdev->dmatb;
int ret;

hstream->period_bytes = 0;/* initialize period_bytes */
hstream->bufsize = sdev->dmatb.bytes;
hstream->bufsize = dmab->bytes;

ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
if (ret < 0)
Expand Down Expand Up @@ -57,7 +56,7 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag)
* initialize capture stream, set BDL address and return corresponding
* stream tag which will be sent to the firmware by IPC message.
*/
ret = hda_dsp_trace_prepare(sdev);
ret = hda_dsp_trace_prepare(sdev, &sdev->dmatb);
if (ret < 0) {
dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret);
hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag);
Expand Down
Loading