Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ced0d765 authored by Rama Krishna Phani A's avatar Rama Krishna Phani A Committed by Gustavo Solaira
Browse files

msm: mhi_dev: Add callback support for kernel clients



Add a callback for kernel clients to receive notification
once the software channel for which the client has registered
has opened/closed.

Change-Id: Ie97e71b5c9e007a659d0f33ac0bf110327494e9e
Signed-off-by: default avatarRama Krishna Phani A <rphani@codeaurora.org>
parent 565eb49e
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -825,6 +825,19 @@ int mhi_dev_send_ee_event(struct mhi_dev *mhi, enum mhi_dev_execenv exec_env)
}
EXPORT_SYMBOL(mhi_dev_send_ee_event);

static void mhi_dev_trigger_cb(void)
{
	struct mhi_dev_ready_cb_info *info;
	enum mhi_ctrl_info state_data;

	list_for_each_entry(info, &mhi_ctx->client_cb_list, list)
		if (info->cb) {
			mhi_ctrl_state_info(info->cb_data.channel, &state_data);
			info->cb_data.ctrl_info = state_data;
			info->cb(&info->cb_data);
		}
}

int mhi_dev_trigger_hw_acc_wakeup(struct mhi_dev *mhi)
{
	int rc = 0;
@@ -985,6 +998,9 @@ send_start_completion_event:
		if (rc)
			pr_err("Error sending command completion event\n");

		/* Trigger callback to clients */
		mhi_dev_trigger_cb();

		mhi_update_state_info(ch_id, MHI_STATE_CONNECTED);
		if (ch_id == MHI_CLIENT_MBIM_OUT) {
			rc = kobject_uevent_env(&mhi_ctx->dev->kobj,
@@ -2397,6 +2413,51 @@ static void mhi_ring_init_cb(void *data)
	queue_work(mhi->ring_init_wq, &mhi->ring_init_cb_work);
}

int mhi_register_state_cb(void (*mhi_state_cb)
				(struct mhi_dev_client_cb_data *cb_data),
				void *data, enum mhi_client_channel channel)
{
	struct mhi_dev_ready_cb_info *cb_info = NULL;

	if (!mhi_ctx) {
		pr_err("MHI device not ready\n");
		return -ENXIO;
	}

	if (channel > MHI_MAX_CHANNELS) {
		pr_err("Invalid channel :%d\n", channel);
		return -EINVAL;
	}

	mutex_lock(&mhi_ctx->mhi_lock);
	cb_info = kmalloc(sizeof(struct mhi_dev_ready_cb_info), GFP_KERNEL);
	if (!cb_info) {
		mutex_unlock(&mhi_ctx->mhi_lock);
		return -ENOMEM;
	}

	cb_info->cb = mhi_state_cb;
	cb_info->cb_data.user_data = data;
	cb_info->cb_data.channel = channel;

	list_add_tail(&cb_info->list, &mhi_ctx->client_cb_list);

	/**
	 * If channel is open during registration, no callback is issued.
	 * Instead return -EEXIST to notify the client. Clients request
	 * is added to the list to notify future state change notification.
	 */
	if (mhi_ctx->ch[channel].state == MHI_DEV_CH_STARTED) {
		mutex_unlock(&mhi_ctx->mhi_lock);
		return -EEXIST;
	}

	mutex_unlock(&mhi_ctx->mhi_lock);

	return 0;
}
EXPORT_SYMBOL(mhi_register_state_cb);

static void mhi_update_state_info(uint32_t uevent_idx, enum mhi_ctrl_info info)
{
	struct mhi_dev_client_cb_reason reason;
@@ -2770,6 +2831,7 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx)

	INIT_LIST_HEAD(&mhi_ctx->event_ring_list);
	INIT_LIST_HEAD(&mhi_ctx->process_ring_list);
	INIT_LIST_HEAD(&mhi_ctx->client_cb_list);
	mutex_init(&mhi_ctx->mhi_lock);
	mutex_init(&mhi_ctx->mhi_event_lock);
	mutex_init(&mhi_ctx->mhi_write_test);
+24 −0
Original line number Diff line number Diff line
@@ -604,6 +604,8 @@ struct mhi_dev {
	/*Register for interrupt*/
	bool				mhi_int;
	bool				mhi_int_en;
	/* Registered client callback list */
	struct list_head		client_cb_list;

	struct kobj_uevent_env		kobj_env;
};
@@ -715,6 +717,7 @@ enum mhi_client_channel {
#define MHI_DEV_UEVENT_CTRL	0

struct mhi_dev_uevent_info {
	enum mhi_client_channel	channel;
	enum mhi_ctrl_info	ctrl_info;
};

@@ -723,6 +726,20 @@ struct mhi_dev_iov {
	uint32_t	buf_size;
};

struct mhi_dev_client_cb_data {
	void			*user_data;
	enum mhi_client_channel	channel;
	enum mhi_ctrl_info	ctrl_info;
};

typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);

struct mhi_dev_ready_cb_info {
	struct list_head		list;
	mhi_state_cb			cb;
	struct mhi_dev_client_cb_data	cb_data;
};

/**
 * mhi_dev_open_channel() - Channel open for a given client done prior
 *		to read/write.
@@ -1247,4 +1264,11 @@ int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);

void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason);

/**
 * mhi_register_state_cb() - Clients can register and receive callback after
 *		MHI channel is connected or disconnected.
 */
int mhi_register_state_cb(void (*mhi_state_cb)
			(struct mhi_dev_client_cb_data *cb_data), void *data,
			enum mhi_client_channel channel);
#endif /* _MHI_H_ */