diff options
| -rw-r--r-- | drivers/soundwire/qcom.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 55678a30cd4a..35ffffd541bd 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -221,6 +221,9 @@ struct qcom_swrm_ctrl { u32 slave_status; u32 wr_fifo_depth; bool clock_stop_not_supported; + /* Per-Slave SCP_ADDRPAGE1/2 shadow; -1 = unknown. */ + s16 page1_cache[SDW_MAX_DEVICES + 1]; + s16 page2_cache[SDW_MAX_DEVICES + 1]; }; struct qcom_swrm_data { @@ -630,6 +633,10 @@ static void qcom_swrm_set_slave_dev_num(struct sdw_bus *bus, mutex_lock(&bus->bus_lock); set_bit(devnum, bus->assigned); mutex_unlock(&bus->bus_lock); + + /* Re-attach resets SCP_ADDRPAGE1/2 to defaults; invalidate. */ + ctrl->page1_cache[devnum] = -1; + ctrl->page2_cache[devnum] = -1; } } @@ -976,17 +983,25 @@ static enum sdw_command_response qcom_swrm_xfer_msg(struct sdw_bus *bus, int ret, i, len; if (msg->page) { - ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page1, - msg->dev_num, - SDW_SCP_ADDRPAGE1); - if (ret) - return ret; + if (ctrl->page1_cache[msg->dev_num] != msg->addr_page1) { + ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page1, + msg->dev_num, + SDW_SCP_ADDRPAGE1); + if (ret) + return ret; - ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page2, - msg->dev_num, - SDW_SCP_ADDRPAGE2); - if (ret) - return ret; + ctrl->page1_cache[msg->dev_num] = msg->addr_page1; + } + + if (ctrl->page2_cache[msg->dev_num] != msg->addr_page2) { + ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page2, + msg->dev_num, + SDW_SCP_ADDRPAGE2); + if (ret) + return ret; + + ctrl->page2_cache[msg->dev_num] = msg->addr_page2; + } } if (msg->flags == SDW_MSG_FLAG_READ) { @@ -1561,6 +1576,9 @@ static int qcom_swrm_probe(struct platform_device *pdev) if (!ctrl) return -ENOMEM; + memset(ctrl->page1_cache, 0xff, sizeof(ctrl->page1_cache)); + memset(ctrl->page2_cache, 0xff, sizeof(ctrl->page2_cache)); + data = of_device_get_match_data(dev); ctrl->max_reg = data->max_reg; ctrl->reg_layout = data->reg_layout; |
