From b22f805bbe090d42e2eed86aa075687e47f924b7 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Tue, 12 Feb 2019 20:05:21 +0800 Subject: HID: intel-ish-hid: Optimize writing ipc message from queue Currently we are using one additional static variable and a spinlock to prevent contention of writing IPC messages to ISH hardware, which is not necessary. Once ISH is ready to accept new data, we can push new data to hardware. This pushing of new data is already protected by wr_processing_spinlock for contention, which is enough. So use this spinlock to check both readiness for accepting new data and once ready allow writing of ipc message from queue to ISH hardware. While here, cleaned up some space after return. Signed-off-by: Hong Liu Tested-by: Hongyan Song Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ipc/ipc.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers/hid/intel-ish-hid/ipc') diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index 742191bb24c6..ff8eca11ff73 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -256,33 +256,22 @@ static int write_ipc_from_queue(struct ishtp_device *dev) int i; void (*ipc_send_compl)(void *); void *ipc_send_compl_prm; - static int out_ipc_locked; - unsigned long out_ipc_flags; if (dev->dev_state == ISHTP_DEV_DISABLED) - return -EINVAL; + return -EINVAL; - spin_lock_irqsave(&dev->out_ipc_spinlock, out_ipc_flags); - if (out_ipc_locked) { - spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); - return -EBUSY; - } - out_ipc_locked = 1; + spin_lock_irqsave(&dev->wr_processing_spinlock, flags); if (!ish_is_input_ready(dev)) { - out_ipc_locked = 0; - spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); + spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); return -EBUSY; } - spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); - spin_lock_irqsave(&dev->wr_processing_spinlock, flags); /* * if tx send list is empty - return 0; * may happen, as RX_COMPLETE handler doesn't check list emptiness. */ if (list_empty(&dev->wr_processing_list)) { spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); - out_ipc_locked = 0; return 0; } @@ -333,7 +322,6 @@ static int write_ipc_from_queue(struct ishtp_device *dev) dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val); ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val); - out_ipc_locked = 0; ipc_send_compl = ipc_link->ipc_send_compl; ipc_send_compl_prm = ipc_link->ipc_send_compl_prm; @@ -914,7 +902,6 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev) init_waitqueue_head(&dev->wait_hw_ready); spin_lock_init(&dev->wr_processing_spinlock); - spin_lock_init(&dev->out_ipc_spinlock); /* Init IPC processing and free lists */ INIT_LIST_HEAD(&dev->wr_processing_list); -- cgit v1.2.3 From 7e06e0d5493b3e88016b247fe92f67a071d2c655 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Tue, 12 Feb 2019 20:05:22 +0800 Subject: HID: intel-ish-hid: move doorbell writing before flush Reading of IPC_REG_ISH_HOST_FWSTS will flush both message register and doorbell. So move the doorbell write before reading of IPC_REG_ISH_HOST_FWSTS. Signed-off-by: Hong Liu Tested-by: Hongyan Song Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ipc/ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid/intel-ish-hid/ipc') diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel-ish-hid/ipc/ipc.c index ff8eca11ff73..30d8a639a5bb 100644 --- a/drivers/hid/intel-ish-hid/ipc/ipc.c +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c @@ -314,6 +314,8 @@ static int write_ipc_from_queue(struct ishtp_device *dev) memcpy(®, &r_buf[length >> 2], rem); ish_reg_write(dev, reg_addr, reg); } + ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val); + /* Flush writes to msg registers and doorbell */ ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); @@ -321,8 +323,6 @@ static int write_ipc_from_queue(struct ishtp_device *dev) ++dev->ipc_tx_cnt; dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val); - ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val); - ipc_send_compl = ipc_link->ipc_send_compl; ipc_send_compl_prm = ipc_link->ipc_send_compl_prm; list_del_init(&ipc_link->link); -- cgit v1.2.3