]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ASoC: Intel: Skylake: large_config_get overhaul
authorCezary Rojewski <cezary.rojewski@intel.com>
Thu, 8 Aug 2019 18:15:49 +0000 (20:15 +0200)
committerMark Brown <broonie@kernel.org>
Thu, 8 Aug 2019 20:22:33 +0000 (21:22 +0100)
LARGE_CONFIG_GET is mainly used to retrieve requested module parameters
but it may also carry TX payload with them. Update its implementation to
account for both TX and RX data.
First reply.header carries total payload size within data_off_sizefield.
Make use of reply.header to realloc returned buffer with correct size.

Failure of IPC request is permissive - error-payload may be returned, an
informative data why GET for given param failed - and thus function
should not collapse before entire processing is finished. Caller is
responsible for checking returned payload and bytes parameters.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20190808181549.12521-3-cezary.rojewski@intel.com
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/intel/skylake/skl-sst-ipc.h

index e8cc710f092bf455ca164a02323b6af5c5c8a52e..84f0e6f58eb502a9ac0c7d24ab5587f58d83251b 100644 (file)
@@ -1379,11 +1379,12 @@ int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
                          u32 param_id, struct skl_module_cfg *mcfg)
 {
        struct skl_ipc_large_config_msg msg;
+       size_t bytes = size;
 
        msg.module_id = mcfg->id.module_id;
        msg.instance_id = mcfg->id.pvt_id;
        msg.param_data_size = size;
        msg.large_param_id = param_id;
 
-       return skl_ipc_get_large_config(&skl->ipc, &msg, params);
+       return skl_ipc_get_large_config(&skl->ipc, &msg, &params, &bytes);
 }
index 196c80dadb1f6909bb89662632abae9621b7ccd4..667cdddc289fd6588462b3fa05dadb4a4c108c24 100644 (file)
@@ -969,12 +969,18 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
 EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
 
 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
-               struct skl_ipc_large_config_msg *msg, u32 *param)
+               struct skl_ipc_large_config_msg *msg,
+               u32 **payload, size_t *bytes)
 {
        struct skl_ipc_header header = {0};
-       struct sst_ipc_message request = {0}, reply = {0};
+       struct sst_ipc_message request, reply = {0};
+       unsigned int *buf;
        int ret;
 
+       reply.data = kzalloc(SKL_ADSP_W1_SZ, GFP_KERNEL);
+       if (!reply.data)
+               return -ENOMEM;
+
        header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
        header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
        header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
@@ -986,13 +992,22 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
        header.extension |= IPC_FINAL_BLOCK(1);
        header.extension |= IPC_INITIAL_BLOCK(1);
 
-       request.header = *(u64 *)(&header);
-       reply.data = param;
-       reply.size = msg->param_data_size;
+       request.header = *(u64 *)&header;
+       request.data = *payload;
+       request.size = *bytes;
+       reply.size = SKL_ADSP_W1_SZ;
+
        ret = sst_ipc_tx_message_wait(ipc, request, &reply);
        if (ret < 0)
                dev_err(ipc->dev, "ipc: get large config fail, err: %d\n", ret);
 
+       reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
+       buf = krealloc(reply.data, reply.size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       *payload = buf;
+       *bytes = reply.size;
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
index 93af08cf41d2d1791a8c0cde02436f5ab20c010b..08ac31778325d36474a8fd73a2e56f365cf28413 100644 (file)
@@ -139,7 +139,8 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
                struct skl_ipc_large_config_msg *msg, u32 *param);
 
 int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
-               struct skl_ipc_large_config_msg *msg, u32 *param);
+               struct skl_ipc_large_config_msg *msg,
+               u32 **payload, size_t *bytes);
 
 int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
                        u8 dma_id, u8 table_id, bool wait);