X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0408-staging-bcm2835-audio-Make-single-vchi-handle.patch;fp=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0408-staging-bcm2835-audio-Make-single-vchi-handle.patch;h=eb6538dff3532b8a56139c05e492754afb0e0b99;hb=67dcc43f3a22dc3a7ac07a7065971b426feeb043;hp=0000000000000000000000000000000000000000;hpb=47a93a810f78adce5a130d287f82b28e9b54313c;p=openwrt%2Fopenwrt.git diff --git a/target/linux/brcm2708/patches-4.19/950-0408-staging-bcm2835-audio-Make-single-vchi-handle.patch b/target/linux/brcm2708/patches-4.19/950-0408-staging-bcm2835-audio-Make-single-vchi-handle.patch new file mode 100644 index 0000000000..eb6538dff3 --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0408-staging-bcm2835-audio-Make-single-vchi-handle.patch @@ -0,0 +1,412 @@ +From 98a1612b199cb3060306c05d1a6d7ca18ef08475 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 4 Sep 2018 17:58:47 +0200 +Subject: [PATCH] staging: bcm2835-audio: Make single vchi handle + +commit 326a6edcb2ada56375bd7d3fc24c83f58e8da7f3 upstream. + +The bcm2835_audio_instance object contains the array of +VCHI_SERVICE_HANDLE_T, while the code assumes and uses only the first +element explicitly. Let's reduce to a single vchi handle for +simplifying the code. + +Signed-off-by: Takashi Iwai +Tested-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman +--- + .../bcm2835-audio/bcm2835-vchiq.c | 170 ++++++------------ + 1 file changed, 58 insertions(+), 112 deletions(-) + +--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +@@ -44,8 +44,7 @@ + #endif + + struct bcm2835_audio_instance { +- unsigned int num_connections; +- VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; ++ VCHI_SERVICE_HANDLE_T vchi_handle; + struct completion msg_avail_comp; + struct mutex vchi_mutex; + struct bcm2835_alsa_stream *alsa_stream; +@@ -202,12 +201,12 @@ static void audio_vchi_callback(void *pa + BUG(); + return; + } +- if (!instance->vchi_handle[0]) { +- LOG_ERR(" .. instance->vchi_handle[0] is null\n"); ++ if (!instance->vchi_handle) { ++ LOG_ERR(" .. instance->vchi_handle is null\n"); + BUG(); + return; + } +- status = vchi_msg_dequeue(instance->vchi_handle[0], ++ status = vchi_msg_dequeue(instance->vchi_handle, + &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); + if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { + LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", +@@ -237,102 +236,61 @@ static void audio_vchi_callback(void *pa + + static struct bcm2835_audio_instance * + vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, +- VCHI_CONNECTION_T **vchi_connections, +- unsigned int num_connections) ++ VCHI_CONNECTION_T *vchi_connection) + { +- unsigned int i; ++ SERVICE_CREATION_T params = { ++ .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), ++ .service_id = VC_AUDIO_SERVER_NAME, ++ .connection = vchi_connection, ++ .rx_fifo_size = 0, ++ .tx_fifo_size = 0, ++ .callback = audio_vchi_callback, ++ .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE ++ .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE ++ .want_crc = 0 ++ }; + struct bcm2835_audio_instance *instance; + int status; +- int ret; +- +- LOG_DBG("%s: start", __func__); + +- if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { +- LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", +- __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); +- +- return ERR_PTR(-EINVAL); +- } + /* Allocate memory for this instance */ + instance = kzalloc(sizeof(*instance), GFP_KERNEL); + if (!instance) + return ERR_PTR(-ENOMEM); + +- instance->num_connections = num_connections; +- + /* Create a lock for exclusive, serialized VCHI connection access */ + mutex_init(&instance->vchi_mutex); + /* Open the VCHI service connections */ +- for (i = 0; i < num_connections; i++) { +- SERVICE_CREATION_T params = { +- .version = VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), +- .service_id = VC_AUDIO_SERVER_NAME, +- .connection = vchi_connections[i], +- .rx_fifo_size = 0, +- .tx_fifo_size = 0, +- .callback = audio_vchi_callback, +- .callback_param = instance, +- .want_unaligned_bulk_rx = 1, //TODO: remove VCOS_FALSE +- .want_unaligned_bulk_tx = 1, //TODO: remove VCOS_FALSE +- .want_crc = 0 +- }; +- +- LOG_DBG("%s: about to open %i\n", __func__, i); +- status = vchi_service_open(vchi_instance, ¶ms, +- &instance->vchi_handle[i]); ++ params.callback_param = instance, + +- LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); +- if (status) { +- LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", +- __func__, status); +- ret = -EPERM; +- goto err_close_services; +- } +- /* Finished with the service for now */ +- vchi_service_release(instance->vchi_handle[i]); +- } +- +- LOG_DBG("%s: okay\n", __func__); +- return instance; ++ status = vchi_service_open(vchi_instance, ¶ms, ++ &instance->vchi_handle); + +-err_close_services: +- for (i = 0; i < instance->num_connections; i++) { +- LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); +- if (instance->vchi_handle[i]) +- vchi_service_close(instance->vchi_handle[i]); ++ if (status) { ++ LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", ++ __func__, status); ++ kfree(instance); ++ return ERR_PTR(-EPERM); + } + +- kfree(instance); +- LOG_ERR("%s: error\n", __func__); ++ /* Finished with the service for now */ ++ vchi_service_release(instance->vchi_handle); + +- return ERR_PTR(ret); ++ return instance; + } + + static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) + { +- unsigned int i; +- +- if (!instance) { +- LOG_ERR("%s: invalid handle %p\n", __func__, instance); +- +- return -1; +- } ++ int status; + +- LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); + mutex_lock(&instance->vchi_mutex); + + /* Close all VCHI service connections */ +- for (i = 0; i < instance->num_connections; i++) { +- int status; +- +- LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); +- vchi_service_use(instance->vchi_handle[i]); ++ vchi_service_use(instance->vchi_handle); + +- status = vchi_service_close(instance->vchi_handle[i]); +- if (status) { +- LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", +- __func__, status); +- } ++ status = vchi_service_close(instance->vchi_handle); ++ if (status) { ++ LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", ++ __func__, status); + } + + mutex_unlock(&instance->vchi_mutex); +@@ -383,19 +341,9 @@ static int bcm2835_audio_open_connection + (struct bcm2835_audio_instance *)alsa_stream->instance; + struct bcm2835_vchi_ctx *vhci_ctx = alsa_stream->chip->vchi_ctx; + +- LOG_INFO("%s: start\n", __func__); +- BUG_ON(instance); +- if (instance) { +- LOG_ERR("%s: VCHI instance already open (%p)\n", +- __func__, instance); +- instance->alsa_stream = alsa_stream; +- alsa_stream->instance = instance; +- return 0; +- } +- + /* Initialize an instance of the audio service */ + instance = vc_vchi_audio_init(vhci_ctx->vchi_instance, +- &vhci_ctx->vchi_connection, 1); ++ vhci_ctx->vchi_connection); + + if (IS_ERR(instance)) { + LOG_ERR("%s: failed to initialize audio service\n", __func__); +@@ -407,8 +355,6 @@ static int bcm2835_audio_open_connection + instance->alsa_stream = alsa_stream; + alsa_stream->instance = instance; + +- LOG_DBG(" success !\n"); +- + return 0; + } + +@@ -431,12 +377,12 @@ int bcm2835_audio_open(struct bcm2835_al + LOG_DBG(" instance (%p)\n", instance); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_OPEN; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -450,7 +396,7 @@ int bcm2835_audio_open(struct bcm2835_al + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + free_wq: +@@ -472,7 +418,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + chip->dest, chip->volume); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + instance->result = -1; + +@@ -487,7 +433,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -511,7 +457,7 @@ int bcm2835_audio_set_ctls(struct bcm283 + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + return ret; +@@ -537,7 +483,7 @@ int bcm2835_audio_set_params(struct bcm2 + } + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + instance->result = -1; + +@@ -550,7 +496,7 @@ int bcm2835_audio_set_params(struct bcm2 + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -574,7 +520,7 @@ int bcm2835_audio_set_params(struct bcm2 + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + return ret; +@@ -588,12 +534,12 @@ static int bcm2835_audio_start_worker(st + int ret; + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_START; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -607,7 +553,7 @@ static int bcm2835_audio_start_worker(st + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + } +@@ -620,13 +566,13 @@ static int bcm2835_audio_stop_worker(str + int ret; + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_STOP; + m.u.stop.draining = alsa_stream->draining; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -640,7 +586,7 @@ static int bcm2835_audio_stop_worker(str + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + } +@@ -655,7 +601,7 @@ int bcm2835_audio_close(struct bcm2835_a + my_workqueue_quit(alsa_stream); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + m.type = VC_AUDIO_MSG_TYPE_CLOSE; + +@@ -663,7 +609,7 @@ int bcm2835_audio_close(struct bcm2835_a + init_completion(&instance->msg_avail_comp); + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -687,7 +633,7 @@ int bcm2835_audio_close(struct bcm2835_a + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + + /* Stop the audio service */ +@@ -708,10 +654,10 @@ static int bcm2835_audio_write_worker(st + LOG_INFO(" Writing %d bytes from %p\n", count, src); + + mutex_lock(&instance->vchi_mutex); +- vchi_service_use(instance->vchi_handle[0]); ++ vchi_service_use(instance->vchi_handle); + + if (instance->peer_version == 0 && +- vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) ++ vchi_get_peer_version(instance->vchi_handle, &instance->peer_version) == 0) + LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); + + m.type = VC_AUDIO_MSG_TYPE_WRITE; +@@ -723,7 +669,7 @@ static int bcm2835_audio_write_worker(st + m.u.write.silence = src == NULL; + + /* Send the message to the videocore */ +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + &m, sizeof(m)); + + if (status) { +@@ -736,7 +682,7 @@ static int bcm2835_audio_write_worker(st + if (!m.u.write.silence) { + if (!m.u.write.max_packet) { + /* Send the message to the videocore */ +- status = vchi_bulk_queue_transmit(instance->vchi_handle[0], ++ status = vchi_bulk_queue_transmit(instance->vchi_handle, + src, count, + 0 * VCHI_FLAGS_BLOCK_UNTIL_QUEUED + + +@@ -746,7 +692,7 @@ static int bcm2835_audio_write_worker(st + while (count > 0) { + int bytes = min_t(int, m.u.write.max_packet, count); + +- status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], ++ status = bcm2835_vchi_msg_queue(instance->vchi_handle, + src, bytes); + src = (char *)src + bytes; + count -= bytes; +@@ -763,7 +709,7 @@ static int bcm2835_audio_write_worker(st + ret = 0; + + unlock: +- vchi_service_release(instance->vchi_handle[0]); ++ vchi_service_release(instance->vchi_handle); + mutex_unlock(&instance->vchi_mutex); + return ret; + }