]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
HID: intel-ish-hid: ishtp: Add dma_no_cache_snooping() callback
authorEven Xu <even.xu@intel.com>
Thu, 10 Jun 2021 06:21:53 +0000 (14:21 +0800)
committerJiri Kosina <jkosina@suse.cz>
Mon, 14 Jun 2021 13:55:09 +0000 (15:55 +0200)
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>
drivers/hid/intel-ish-hid/ishtp/client.c
drivers/hid/intel-ish-hid/ishtp/ishtp-dev.h

index 585a5c4066cb3bb32a862ed6d8f24da3b3f415a0..405e0d5212cc8d35f1a0c9ba098e408fe9a54a13 100644 (file)
@@ -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;
 
index f579b16e6d7a9f8e0cec57415b9947f6792d1ed2..32142c7d9a04382259e6760f1b046721477f0916 100644 (file)
@@ -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);
 };
 
 /**