1
0
Fork 0

ASoC: Make creation of machine device from SOF core optional

Currently, SOF probes machine drivers by creating a platform device
and passing the machine description as private data.

This is driven by the ACPI restrictions. Ideally, ACPI tables
should contain the description for the machine driver. This is
not possible because ACPI tables are frozen and used on multiple
OS-es (e.g Windows).

In the case, of Device Tree we don't have this restrictions, so we
choose to probe the machine drivers by creating a DT node as is
the standard ALSA way.

This patch makes the probing of machine drivers from SOF core optional
allowing for arm platforms to decouple the SOF core from machine
driver probing.

Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
5.4-rM2-2.2.x-imx-squashed
Daniel Baluta 2019-11-07 18:54:01 +02:00
parent 3d9382581a
commit 19fa41a7ab
7 changed files with 107 additions and 23 deletions

View File

@ -197,7 +197,7 @@ EXPORT_SYMBOL(snd_sof_get_status);
/*
* SOF Driver enumeration.
*/
static int sof_machine_check(struct snd_sof_dev *sdev)
int sof_machine_check(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
#if IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)
@ -228,13 +228,45 @@ static int sof_machine_check(struct snd_sof_dev *sdev)
return 0;
#endif
}
EXPORT_SYMBOL(sof_machine_check);
int sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
{
struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata;
const char *drv_name;
const void *mach;
int size;
drv_name = plat_data->machine->drv_name;
mach = (const void *)plat_data->machine;
size = sizeof(*plat_data->machine);
/* register machine driver, pass machine info as pdata */
plat_data->pdev_mach =
platform_device_register_data(sdev->dev, drv_name,
PLATFORM_DEVID_NONE, mach, size);
if (IS_ERR(plat_data->pdev_mach))
return PTR_ERR(plat_data->pdev_mach);
dev_dbg(sdev->dev, "created machine %s\n",
dev_name(&plat_data->pdev_mach->dev));
return 0;
}
EXPORT_SYMBOL(sof_machine_register);
void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
{
struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata;
if (!IS_ERR_OR_NULL(plat_data->pdev_mach))
platform_device_unregister(plat_data->pdev_mach);
}
EXPORT_SYMBOL(sof_machine_unregister);
static int sof_probe_continue(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *plat_data = sdev->pdata;
const char *drv_name;
const void *mach;
int size;
int ret;
/* probe the DSP hardware */
@ -245,7 +277,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
}
/* check machine info */
ret = sof_machine_check(sdev);
ret = snd_sof_machine_check(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to get machine info %d\n",
ret);
@ -312,22 +344,9 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
goto fw_run_err;
}
drv_name = plat_data->machine->drv_name;
mach = (const void *)plat_data->machine;
size = sizeof(*plat_data->machine);
/* register machine driver, pass machine info as pdata */
plat_data->pdev_mach =
platform_device_register_data(sdev->dev, drv_name,
PLATFORM_DEVID_NONE, mach, size);
if (IS_ERR(plat_data->pdev_mach)) {
ret = PTR_ERR(plat_data->pdev_mach);
ret = snd_sof_machine_register(sdev, plat_data);
if (ret < 0)
goto fw_run_err;
}
dev_dbg(sdev->dev, "created machine %s\n",
dev_name(&plat_data->pdev_mach->dev));
/*
* Some platforms in SOF, ex: BYT, may not have their platform PM
@ -453,9 +472,7 @@ int snd_sof_device_remove(struct device *dev)
* will remove the component driver and unload the topology
* before freeing the snd_card.
*/
if (!IS_ERR_OR_NULL(pdata->pdev_mach))
platform_device_unregister(pdata->pdev_mach);
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

View File

@ -53,6 +53,11 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
.ipc_msg_data = hda_ipc_msg_data,
.ipc_pcm_params = hda_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = apl_dsp_debugfs,
.debug_map_count = ARRAY_SIZE(apl_dsp_debugfs),

View File

@ -554,6 +554,11 @@ const struct snd_sof_dsp_ops sof_bdw_ops = {
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = bdw_debugfs,
.debug_map_count = ARRAY_SIZE(bdw_debugfs),

View File

@ -493,6 +493,11 @@ const struct snd_sof_dsp_ops sof_tng_ops = {
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = byt_debugfs,
.debug_map_count = ARRAY_SIZE(byt_debugfs),
@ -654,6 +659,11 @@ const struct snd_sof_dsp_ops sof_byt_ops = {
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = byt_debugfs,
.debug_map_count = ARRAY_SIZE(byt_debugfs),
@ -713,6 +723,11 @@ const struct snd_sof_dsp_ops sof_cht_ops = {
.ipc_msg_data = intel_ipc_msg_data,
.ipc_pcm_params = intel_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = cht_debugfs,
.debug_map_count = ARRAY_SIZE(cht_debugfs),

View File

@ -211,6 +211,11 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
.ipc_msg_data = hda_ipc_msg_data,
.ipc_pcm_params = hda_ipc_pcm_params,
/* machine driver */
.machine_check = sof_machine_check,
.machine_register = sof_machine_register,
.machine_unregister = sof_machine_unregister,
/* debug */
.debug_map = cnl_dsp_debugfs,
.debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs),

View File

@ -381,6 +381,32 @@ snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
return 0;
}
/* machine driver */
static inline int
snd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
{
if (sof_ops(sdev) && sof_ops(sdev)->machine_register)
return sof_ops(sdev)->machine_register(sdev, pdata);
return 0;
}
static inline void
snd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
{
if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister)
sof_ops(sdev)->machine_unregister(sdev, pdata);
}
static inline int
snd_sof_machine_check(struct snd_sof_dev *sdev)
{
if (sof_ops(sdev) && sof_ops(sdev)->machine_check)
return sof_ops(sdev)->machine_check(sdev);
return 0;
}
static inline const struct snd_sof_dsp_ops
*sof_get_ops(const struct sof_dev_desc *d,
const struct sof_ops_table mach_ops[], int asize)

View File

@ -202,6 +202,13 @@ struct snd_sof_dsp_ops {
int (*get_window_offset)(struct snd_sof_dev *sdev,
u32 id);/* mandatory for common loader code */
/* machine driver ops */
int (*machine_register)(struct snd_sof_dev *sdev,
void *pdata); /* optional */
void (*machine_unregister)(struct snd_sof_dev *sdev,
void *pdata); /* optional */
int (*machine_check)(struct snd_sof_dev *sdev); /* optional */
/* DAI ops */
struct snd_soc_dai_driver *drv;
int num_drv;
@ -462,6 +469,10 @@ int snd_sof_create_page_table(struct device *dev,
struct snd_dma_buffer *dmab,
unsigned char *page_table, size_t size);
int sof_machine_register(struct snd_sof_dev *sdev, void *pdata);
void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata);
int sof_machine_check(struct snd_sof_dev *sdev);
/*
* Firmware loading.
*/