Staging driver fixes for 6.16-rc6

Here are some small driver fixes for the vchiq_arm staging driver:
   - reverts of previous changes that turned out to caused problems.
   - change to prevent a research leak
 
 All of these have been in linux-next this week with no reported
 problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaHzHKw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ymrxgCeLpzzCQSZ5NQCUEEfSKuRGJaVoJoAn0lyY7bm
 YK29QmrdA96E+h4v4W2f
 =iSQD
 -----END PGP SIGNATURE-----

Merge tag 'staging-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes from Greg KH:
 "Here are some small driver fixes for the vchiq_arm staging driver:

   - reverts of previous changes that turned out to caused problems.

   - change to prevent a resource leak

  All of these have been in linux-next this week with no reported
  problems"

* tag 'staging-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: vchiq_arm: Make vchiq_shutdown never fail
  Revert "staging: vchiq_arm: Create keep-alive thread during probe"
  Revert "staging: vchiq_arm: Improve initial VCHIQ connect"
This commit is contained in:
Linus Torvalds 2025-07-20 09:08:55 -07:00
commit b933c72d65
3 changed files with 56 additions and 45 deletions

View File

@ -97,6 +97,13 @@ struct vchiq_arm_state {
* tracked separately with the state.
*/
int peer_use_count;
/*
* Flag to indicate that the first vchiq connect has made it through.
* This means that both sides should be fully ready, and we should
* be able to suspend after this point.
*/
int first_connect;
};
static int
@ -273,6 +280,29 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state
return 0;
}
int
vchiq_platform_init_state(struct vchiq_state *state)
{
struct vchiq_arm_state *platform_state;
platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL);
if (!platform_state)
return -ENOMEM;
rwlock_init(&platform_state->susp_res_lock);
init_completion(&platform_state->ka_evt);
atomic_set(&platform_state->ka_use_count, 0);
atomic_set(&platform_state->ka_use_ack_count, 0);
atomic_set(&platform_state->ka_release_count, 0);
platform_state->state = state;
state->platform_state = (struct opaque_platform_state *)platform_state;
return 0;
}
static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *state)
{
return (struct vchiq_arm_state *)state->platform_state;
@ -363,8 +393,7 @@ int vchiq_shutdown(struct vchiq_instance *instance)
struct vchiq_state *state = instance->state;
int ret = 0;
if (mutex_lock_killable(&state->mutex))
return -EAGAIN;
mutex_lock(&state->mutex);
/* Remove all services */
vchiq_shutdown_internal(state, instance);
@ -981,39 +1010,6 @@ vchiq_keepalive_thread_func(void *v)
return 0;
}
int
vchiq_platform_init_state(struct vchiq_state *state)
{
struct vchiq_arm_state *platform_state;
char threadname[16];
platform_state = devm_kzalloc(state->dev, sizeof(*platform_state), GFP_KERNEL);
if (!platform_state)
return -ENOMEM;
snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
state->id);
platform_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func,
(void *)state, threadname);
if (IS_ERR(platform_state->ka_thread)) {
dev_err(state->dev, "couldn't create thread %s\n", threadname);
return PTR_ERR(platform_state->ka_thread);
}
rwlock_init(&platform_state->susp_res_lock);
init_completion(&platform_state->ka_evt);
atomic_set(&platform_state->ka_use_count, 0);
atomic_set(&platform_state->ka_use_ack_count, 0);
atomic_set(&platform_state->ka_release_count, 0);
platform_state->state = state;
state->platform_state = (struct opaque_platform_state *)platform_state;
return 0;
}
int
vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service,
enum USE_TYPE_E use_type)
@ -1329,19 +1325,37 @@ vchiq_check_service(struct vchiq_service *service)
return ret;
}
void vchiq_platform_connected(struct vchiq_state *state)
{
struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
wake_up_process(arm_state->ka_thread);
}
void vchiq_platform_conn_state_changed(struct vchiq_state *state,
enum vchiq_connstate oldstate,
enum vchiq_connstate newstate)
{
struct vchiq_arm_state *arm_state = vchiq_platform_get_arm_state(state);
char threadname[16];
dev_dbg(state->dev, "suspend: %d: %s->%s\n",
state->id, get_conn_state_name(oldstate), get_conn_state_name(newstate));
if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED)
return;
write_lock_bh(&arm_state->susp_res_lock);
if (arm_state->first_connect) {
write_unlock_bh(&arm_state->susp_res_lock);
return;
}
arm_state->first_connect = 1;
write_unlock_bh(&arm_state->susp_res_lock);
snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
state->id);
arm_state->ka_thread = kthread_create(&vchiq_keepalive_thread_func,
(void *)state,
threadname);
if (IS_ERR(arm_state->ka_thread)) {
dev_err(state->dev, "suspend: Couldn't create thread %s\n",
threadname);
} else {
wake_up_process(arm_state->ka_thread);
}
}
static const struct of_device_id vchiq_of_match[] = {

View File

@ -3343,7 +3343,6 @@ vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instanc
return -EAGAIN;
vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
vchiq_platform_connected(state);
complete(&state->connect);
}

View File

@ -575,8 +575,6 @@ int vchiq_send_remote_use(struct vchiq_state *state);
int vchiq_send_remote_use_active(struct vchiq_state *state);
void vchiq_platform_connected(struct vchiq_state *state);
void vchiq_platform_conn_state_changed(struct vchiq_state *state,
enum vchiq_connstate oldstate,
enum vchiq_connstate newstate);