summaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorEven Xu <even.xu@intel.com>2021-06-10 09:21:53 +0300
committerJiri Kosina <jkosina@suse.cz>2021-06-14 16:55:09 +0300
commit4aae88b9a9749f5b1c74f004ed8bd8efbaa96440 (patch)
treefd43142094da5796d3db2b9f7f725a229d32e474 /drivers/hid
parent65e4122d2ea758a1834a5ddf9c555a4d2c1dd66a (diff)
downloadlinux-4aae88b9a9749f5b1c74f004ed8bd8efbaa96440.tar.xz
HID: intel-ish-hid: ishtp: Add dma_no_cache_snooping() callback
Different platforms have different DMA capability, on most of platforms, DMA support cache snooping. But few platforms, such as ElkhartLake (EHL), don't support cache snooping which requires cache flush from driver. So add a hardware level callback to let ishtp driver know if cache flush is needed. As most of platform support cache snooping, so driver will not do cache flush by default, until platform implements this callback and return true explicitly. Acked-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com> Signed-off-by: Even Xu <even.xu@intel.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/client.c18
-rw-r--r--drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h1
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c
index 585a5c4066cb..405e0d5212cc 100644
--- a/drivers/hid/intel-ish-hid/ishtp/client.c
+++ b/drivers/hid/intel-ish-hid/ishtp/client.c
@@ -10,6 +10,7 @@
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
#include "hbm.h"
#include "client.h"
@@ -772,6 +773,14 @@ static void ishtp_cl_send_msg_dma(struct ishtp_device *dev,
/* write msg to dma buf */
memcpy(msg_addr, cl_msg->send_buf.data, cl_msg->send_buf.size);
+ /*
+ * if current fw don't support cache snooping, driver have to
+ * flush the cache manually.
+ */
+ if (dev->ops->dma_no_cache_snooping &&
+ dev->ops->dma_no_cache_snooping(dev))
+ clflush_cache_range(msg_addr, cl_msg->send_buf.size);
+
/* send dma_xfer hbm msg */
off = msg_addr - (unsigned char *)dev->ishtp_host_dma_tx_buf;
ishtp_hbm_hdr(&hdr, sizeof(struct dma_xfer_hbm));
@@ -996,6 +1005,15 @@ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg,
}
buffer = rb->buffer.data;
+
+ /*
+ * if current fw don't support cache snooping, driver have to
+ * flush the cache manually.
+ */
+ if (dev->ops->dma_no_cache_snooping &&
+ dev->ops->dma_no_cache_snooping(dev))
+ clflush_cache_range(msg, hbm->msg_length);
+
memcpy(buffer, msg, hbm->msg_length);
rb->buf_idx = hbm->msg_length;
diff --git a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
index f579b16e6d7a..32142c7d9a04 100644
--- a/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
+++ b/drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h
@@ -119,6 +119,7 @@ struct ishtp_hw_ops {
unsigned long buffer_length);
uint32_t (*get_fw_status)(struct ishtp_device *dev);
void (*sync_fw_clock)(struct ishtp_device *dev);
+ bool (*dma_no_cache_snooping)(struct ishtp_device *dev);
};
/**