summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2016-11-15 15:02:01 +0100
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:54:20 +0900
commit4d51a52ad6b74d77a96cd1cb22e38b803866c0af (patch)
tree653403063d5e9bffda60341d920b2f198d255123
parent5e2a3bcd50dd0e99c697343ea19c11e84f930062 (diff)
drm/bridge/sii8620: add continuations to messages
Due to asynchronous nature of MHL flow of execution is dispersed. Logical continuation of some actions happens after response of peer, i.e in interrupt handler. To simplify coding continuation mechanism has been added - it is now possible to provide continuation callback, which will be called after peer responds to given action. Change-Id: I93a9d25912e17787dd9856b65d1fc75b2644b940 Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
-rw-r--r--drivers/gpu/drm/bridge/sil-sii8620.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 2cb2195cb631..d6f70c9f1344 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -87,12 +87,15 @@ struct sii8620_mt_msg;
typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
struct sii8620_mt_msg *msg);
+typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
+
struct sii8620_mt_msg {
struct list_head node;
u8 reg[4];
u8 ret;
sii8620_mt_msg_cb send;
sii8620_mt_msg_cb recv;
+ sii8620_cb continuation;
};
static const u8 sii8620_i2c_page[] = {
@@ -262,6 +265,8 @@ static void sii8620_mt_work(struct sii8620 *ctx)
node);
if (msg->recv)
msg->recv(ctx, msg);
+ if (msg->continuation)
+ msg->continuation(ctx, msg->ret);
list_del(&msg->node);
kfree(msg);
}
@@ -314,6 +319,21 @@ static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx)
return msg;
}
+static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont)
+{
+ struct sii8620_mt_msg *msg;
+
+ if (ctx->error)
+ return;
+
+ if (list_empty(&ctx->mt_queue)) {
+ ctx->error = -EINVAL;
+ return;
+ }
+ msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node);
+ msg->continuation = cont;
+}
+
static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2)
{
struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx);