Skip to content

Commit

Permalink
ALSA: hda: move Intel SoundWire ACPI scan to dedicated module
Browse files Browse the repository at this point in the history
The ACPI scan capabilities is called from the intel-dspconfig as well
as the SOF/HDaudio drivers. This creates dependencies and randconfig issues
when HDaudio and SOF/SoundWire are not all configured as modules.

To simplify Kconfig dependencies between HDAudio, SoundWire, SOF and
intel-dspconfig, move the ACPI scan helpers to a dedicated
module. This follows the same idea as NHLT helpers which are already
handled as a dedicated module.

The only functional change is that the kernel parameter to filter
links is now handled by a different module, but that was only provided
for developers needing work-arounds for early BIOS releases.

Reported-by: Arnd Bergmann <[email protected]>
Signed-off-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Kai Vehmanen <[email protected]>
Reviewed-by: Guennadi Liakhovetski <[email protected]>
Reviewed-by: Bard Liao <[email protected]>
Acked-by: Mark Brown <[email protected]>
Acked-by: Vinod Koul <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
plbossart authored and tiwai committed Mar 2, 2021
1 parent cf5807f commit 08c2a4b
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 161 deletions.
2 changes: 0 additions & 2 deletions drivers/soundwire/intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ struct sdw_intel {
#endif
};

#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1)

int intel_master_startup(struct platform_device *pdev);
int intel_master_process_wakeen_event(struct platform_device *pdev);

Expand Down
158 changes: 0 additions & 158 deletions drivers/soundwire/intel_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,12 @@
#include "cadence_master.h"
#include "intel.h"

#define SDW_LINK_TYPE 4 /* from Intel ACPI documentation */
#define SDW_MAX_LINKS 4
#define SDW_SHIM_LCAP 0x0
#define SDW_SHIM_BASE 0x2C000
#define SDW_ALH_BASE 0x2C800
#define SDW_LINK_BASE 0x30000
#define SDW_LINK_SIZE 0x10000

static int ctrl_link_mask;
module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");

static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
{
struct fwnode_handle *link;
char name[32];
u32 quirk_mask = 0;

/* Find master handle */
snprintf(name, sizeof(name),
"mipi-sdw-link-%d-subproperties", i);

link = fwnode_get_named_child_node(fw_node, name);
if (!link)
return false;

fwnode_property_read_u32(link,
"intel-quirk-mask",
&quirk_mask);

if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
return false;

return true;
}

static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
{
struct sdw_intel_link_res *link = ctx->links;
Expand Down Expand Up @@ -81,74 +51,6 @@ static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
return 0;
}

static int
sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
{
struct acpi_device *adev;
int ret, i;
u8 count;

if (acpi_bus_get_device(info->handle, &adev))
return -EINVAL;

/* Found controller, find links supported */
count = 0;
ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
"mipi-sdw-master-count", &count, 1);

/*
* In theory we could check the number of links supported in
* hardware, but in that step we cannot assume SoundWire IP is
* powered.
*
* In addition, if the BIOS doesn't even provide this
* 'master-count' property then all the inits based on link
* masks will fail as well.
*
* We will check the hardware capabilities in the startup() step
*/

if (ret) {
dev_err(&adev->dev,
"Failed to read mipi-sdw-master-count: %d\n", ret);
return -EINVAL;
}

/* Check count is within bounds */
if (count > SDW_MAX_LINKS) {
dev_err(&adev->dev, "Link count %d exceeds max %d\n",
count, SDW_MAX_LINKS);
return -EINVAL;
}

if (!count) {
dev_warn(&adev->dev, "No SoundWire links detected\n");
return -EINVAL;
}
dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count);

info->count = count;
info->link_mask = 0;

for (i = 0; i < count; i++) {
if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
dev_dbg(&adev->dev,
"Link %d masked, will not be enabled\n", i);
continue;
}

if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
dev_dbg(&adev->dev,
"Link %d not selected in firmware\n", i);
continue;
}

info->link_mask |= BIT(i);
}

return 0;
}

#define HDA_DSP_REG_ADSPIC2 (0x10)
#define HDA_DSP_REG_ADSPIS2 (0x14)
#define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
Expand Down Expand Up @@ -357,66 +259,6 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
return 0;
}

static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
void *cdata, void **return_value)
{
struct sdw_intel_acpi_info *info = cdata;
struct acpi_device *adev;
acpi_status status;
u64 adr;

status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
if (ACPI_FAILURE(status))
return AE_OK; /* keep going */

if (acpi_bus_get_device(handle, &adev)) {
pr_err("%s: Couldn't find ACPI handle\n", __func__);
return AE_NOT_FOUND;
}

info->handle = handle;

/*
* On some Intel platforms, multiple children of the HDAS
* device can be found, but only one of them is the SoundWire
* controller. The SNDW device is always exposed with
* Name(_ADR, 0x40000000), with bits 31..28 representing the
* SoundWire link so filter accordingly
*/
if (FIELD_GET(GENMASK(31, 28), adr) != SDW_LINK_TYPE)
return AE_OK; /* keep going */

/* device found, stop namespace walk */
return AE_CTRL_TERMINATE;
}

/**
* sdw_intel_acpi_scan() - SoundWire Intel init routine
* @parent_handle: ACPI parent handle
* @info: description of what firmware/DSDT tables expose
*
* This scans the namespace and queries firmware to figure out which
* links to enable. A follow-up use of sdw_intel_probe() and
* sdw_intel_startup() is required for creation of devices and bus
* startup
*/
int sdw_intel_acpi_scan(acpi_handle *parent_handle,
struct sdw_intel_acpi_info *info)
{
acpi_status status;

info->handle = NULL;
status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
parent_handle, 1,
sdw_intel_acpi_cb,
NULL, info, NULL);
if (ACPI_FAILURE(status) || info->handle == NULL)
return -ENODEV;

return sdw_intel_scan_controller(info);
}
EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SOUNDWIRE_INTEL_INIT);

/**
* sdw_intel_probe() - SoundWire Intel probe routine
* @res: resource data
Expand Down
2 changes: 2 additions & 0 deletions include/linux/soundwire/sdw_intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,6 @@ void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable);

irqreturn_t sdw_intel_thread(int irq, void *dev_id);

#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE BIT(1)

#endif
4 changes: 4 additions & 0 deletions sound/hda/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ config SND_INTEL_NHLT
config SND_INTEL_DSP_CONFIG
tristate
select SND_INTEL_NHLT if ACPI
select SND_INTEL_SOUNDWIRE_ACPI if ACPI
# this config should be selected only for Intel DSP platforms.
# A fallback is provided so that the code compiles in all cases.

config SND_INTEL_SOUNDWIRE_ACPI
tristate

config SND_INTEL_BYT_PREFER_SOF
bool "Prefer SOF driver over SST on BY/CHT platforms"
depends on SND_SST_ATOM_HIFI2_PLATFORM_ACPI && SND_SOC_SOF_BAYTRAIL
Expand Down
3 changes: 3 additions & 0 deletions sound/hda/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/
snd-intel-dspcfg-objs := intel-dsp-config.o
snd-intel-dspcfg-$(CONFIG_SND_INTEL_NHLT) += intel-nhlt.o
obj-$(CONFIG_SND_INTEL_DSP_CONFIG) += snd-intel-dspcfg.o

snd-intel-sdw-acpi-objs := intel-sdw-acpi.o
obj-$(CONFIG_SND_INTEL_SOUNDWIRE_ACPI) += snd-intel-sdw-acpi.o
2 changes: 1 addition & 1 deletion sound/hda/intel-dsp-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,4 @@ EXPORT_SYMBOL_GPL(snd_intel_acpi_dsp_driver_probe);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel DSP config driver");
MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
MODULE_IMPORT_NS(SND_INTEL_SOUNDWIRE_ACPI);
Loading

0 comments on commit 08c2a4b

Please sign in to comment.