summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeung-Woo Kim <sw0312.kim@samsung.com>2021-09-17 13:58:58 +0900
committerSeung-Woo Kim <sw0312.kim@samsung.com>2021-09-17 15:37:51 +0900
commit89ea13b5ecb6424184184260def2ad0a70f551cf (patch)
tree4c5dd79e9c343ee886daca1666c7126bfa105f20
parent0056c18c0b4e742a210725901faf07d005a3de61 (diff)
downloademulator-kernel-tizen_6.5.m2_release.tar.gz
emulator-kernel-tizen_6.5.m2_release.tar.bz2
emulator-kernel-tizen_6.5.m2_release.zip
maru power_supply has get and set operations to qemu with virtio queue and they can be called multiple times, but only one flag is used to check virtio queue req & res state. This causes virtio queue req & res wait mechanism cannot wake. Add operation lock to resolve this. Change-Id: Ia9c4549160df8ac86cceb7c478f7f2767c42bcf5 Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
-rw-r--r--drivers/maru/maru_power_supply.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/maru/maru_power_supply.c b/drivers/maru/maru_power_supply.c
index 612b5b34f1d7..b9535136edc9 100644
--- a/drivers/maru/maru_power_supply.c
+++ b/drivers/maru/maru_power_supply.c
@@ -81,6 +81,7 @@ struct virtio_power {
int flags;
struct mutex lock;
+ struct mutex op_lock;
};
enum power_types {
@@ -149,6 +150,7 @@ static void set_power_data(int type, const char* buf)
return;
}
+ mutex_lock(&v_power->op_lock);
mutex_lock(&v_power->lock);
memset(power_data, 0, __MAX_BUF_POWER);
memset(&v_power->msginfo, 0, sizeof(v_power->msginfo));
@@ -166,10 +168,12 @@ static void set_power_data(int type, const char* buf)
err = virtqueue_add_outbuf(v_power->vq, v_power->sg_vq, 1, &v_power->msginfo, GFP_ATOMIC);
if (err < 0) {
DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err);
+ mutex_unlock(&v_power->op_lock);
return;
}
virtqueue_kick(v_power->vq);
+ mutex_unlock(&v_power->op_lock);
}
static int get_power_data(int type, char* data)
@@ -182,6 +186,7 @@ static int get_power_data(int type, char* data)
return -1;
}
+ mutex_lock(&v_power->op_lock);
mutex_lock(&v_power->lock);
memset(&v_power->msginfo, 0, sizeof(v_power->msginfo));
@@ -197,6 +202,7 @@ static int get_power_data(int type, char* data)
err = virtqueue_add_sgs(v_power->vq, sgs, 1, 1, &v_power->msginfo, GFP_ATOMIC);
if (err < 0) {
DLOG(KERN_ERR, "failed to add buffer to virtqueue (err = %d)", err);
+ mutex_unlock(&v_power->op_lock);
return -1;
}
@@ -208,6 +214,7 @@ static int get_power_data(int type, char* data)
v_power->flags = 0;
memcpy(data, power_data, strlen(power_data));
mutex_unlock(&v_power->lock);
+ mutex_unlock(&v_power->op_lock);
return 0;
}
@@ -356,6 +363,7 @@ static int power_probe(struct virtio_device* dev)
}
mutex_init(&v_power->lock);
+ mutex_init(&v_power->op_lock);
DLOG(KERN_INFO, "Power probe completes");