Skip to content

Commit

Permalink
soundwire: intel: add probe-time check on link id
Browse files Browse the repository at this point in the history
In older platforms, the number of links was constant and hard-coded to
4. Newer platforms can have varying number of links, so we need to add
a probe-time check to make sure the ACPI-reported information with
_DSD properties is aligned with hardware capabilities reported in the
SoundWire LCAP register.

Acked-by: Vinod Koul <[email protected]>
Signed-off-by: Pierre-Louis Bossart <[email protected]>
Reviewed-by: Péter Ujfalusi <[email protected]>
Signed-off-by: Bard Liao <[email protected]>
Acked-by: Mark Brown <[email protected]>
Reviewed-by: Takashi Iwai <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
plbossart authored and broonie committed Aug 19, 2024
1 parent b27404b commit d223459
Showing 4 changed files with 44 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/soundwire/intel.h
Original file line number Diff line number Diff line change
@@ -222,6 +222,13 @@ static inline bool sdw_intel_sync_check_cmdsync_unlocked(struct sdw_intel *sdw)
return false;
}

static inline int sdw_intel_get_link_count(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, get_link_count))
return SDW_INTEL_OPS(sdw, get_link_count)(sdw);
return 4; /* default on older generations */
}

/* common bus management */
int intel_start_bus(struct sdw_intel *sdw);
int intel_start_bus_after_reset(struct sdw_intel *sdw);
20 changes: 20 additions & 0 deletions drivers/soundwire/intel_ace2x.c
Original file line number Diff line number Diff line change
@@ -706,10 +706,30 @@ static void intel_program_sdi(struct sdw_intel *sdw, int dev_num)
__func__, sdw->instance, dev_num);
}

static int intel_get_link_count(struct sdw_intel *sdw)
{
int ret;

ret = hdac_bus_eml_get_count(sdw->link_res->hbus, true, AZX_REG_ML_LEPTR_ID_SDW);
if (!ret) {
dev_err(sdw->cdns.dev, "%s: could not retrieve link count\n", __func__);
return -ENODEV;
}

if (ret > SDW_INTEL_MAX_LINKS) {
dev_err(sdw->cdns.dev, "%s: link count %d exceed max %d\n", __func__, ret, SDW_INTEL_MAX_LINKS);
return -EINVAL;
}

return ret;
}

const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops = {
.debugfs_init = intel_ace2x_debugfs_init,
.debugfs_exit = intel_ace2x_debugfs_exit,

.get_link_count = intel_get_link_count,

.register_dai = intel_register_dai,

.check_clock_stop = intel_check_clock_stop,
14 changes: 14 additions & 0 deletions drivers/soundwire/intel_auxdevice.c
Original file line number Diff line number Diff line change
@@ -317,6 +317,20 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
bus->link_id = auxdev->id;
bus->clk_stop_timeout = 1;

/*
* paranoia check: make sure ACPI-reported number of links is aligned with
* hardware capabilities.
*/
ret = sdw_intel_get_link_count(sdw);
if (ret < 0) {
dev_err(dev, "%s: sdw_intel_get_link_count failed: %d\n", __func__, ret);
return ret;
}
if (ret <= sdw->instance) {
dev_err(dev, "%s: invalid link id %d, link count %d\n", __func__, auxdev->id, ret);
return -EINVAL;
}

sdw_cdns_probe(cdns);

/* Set ops */
3 changes: 3 additions & 0 deletions include/linux/soundwire/sdw_intel.h
Original file line number Diff line number Diff line change
@@ -388,6 +388,7 @@ struct sdw_intel;
/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
* @debugfs_init: initialize all debugfs capabilities
* @debugfs_exit: close and cleanup debugfs capabilities
* @get_link_count: fetch link count from hardware registers
* @register_dai: read all PDI information and register DAIs
* @check_clock_stop: throw error message if clock is not stopped.
* @start_bus: normal start
@@ -412,6 +413,8 @@ struct sdw_intel_hw_ops {
void (*debugfs_init)(struct sdw_intel *sdw);
void (*debugfs_exit)(struct sdw_intel *sdw);

int (*get_link_count)(struct sdw_intel *sdw);

int (*register_dai)(struct sdw_intel *sdw);

void (*check_clock_stop)(struct sdw_intel *sdw);

0 comments on commit d223459

Please sign in to comment.