Commit b933c72d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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"
parents ecf11d31 f2b8ebfb
Loading
Loading
Loading
Loading
+56 −42
Original line number Diff line number Diff line
@@ -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[] = {
+0 −1
Original line number Diff line number Diff line
@@ -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);
	}

+0 −2
Original line number Diff line number Diff line
@@ -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);