maru: power_supply: add operation lock 10/264410/1 accepted/tizen_6.5_unified tizen_6.5 accepted/tizen/6.5/unified/20211028.225311 accepted/tizen/unified/20210923.012133 submit/tizen/20210917.074043 submit/tizen_6.5/20211028.164101 tizen_6.5.m2_release
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Fri, 17 Sep 2021 04:58:58 +0000 (13:58 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Fri, 17 Sep 2021 06:37:51 +0000 (15:37 +0900)
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>
drivers/maru/maru_power_supply.c

index 612b5b3..b953513 100644 (file)
@@ -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");