summary refs log tree commit diff
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/eeprom/at24.c1
-rw-r--r--drivers/misc/fastrpc.c6
-rw-r--r--drivers/misc/habanalabs/common/command_buffer.c9
-rw-r--r--drivers/misc/habanalabs/common/device.c16
-rw-r--r--drivers/misc/habanalabs/common/habanalabs.h14
-rw-r--r--drivers/misc/habanalabs/common/hw_queue.c19
-rw-r--r--drivers/misc/habanalabs/common/irq.c17
-rw-r--r--drivers/misc/habanalabs/common/memory.c1
-rw-r--r--drivers/misc/habanalabs/gaudi/gaudi.c40
-rw-r--r--drivers/misc/habanalabs/gaudi/gaudiP.h1
-rw-r--r--drivers/misc/habanalabs/gaudi/gaudi_coresight.c5
-rw-r--r--drivers/misc/habanalabs/goya/goya.c26
-rw-r--r--drivers/misc/habanalabs/goya/goyaP.h2
-rw-r--r--drivers/misc/habanalabs/include/gaudi/gaudi_masks.h1
-rw-r--r--drivers/misc/lkdtm/Makefile1
-rw-r--r--drivers/misc/mei/Kconfig10
-rw-r--r--drivers/misc/mei/Makefile3
-rw-r--r--drivers/misc/mei/client.h4
-rw-r--r--drivers/misc/mei/hw-virtio.c874
19 files changed, 80 insertions, 970 deletions
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 1c0a41803bb6..926408b41270 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -736,7 +736,6 @@ static int at24_probe(struct i2c_client *client)
 
 	nvmem_config.type = NVMEM_TYPE_EEPROM;
 	nvmem_config.dev = dev;
-	nvmem_config.id = NVMEM_DEVID_AUTO;
 	nvmem_config.read_only = !writable;
 	nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO);
 	nvmem_config.owner = THIS_MODULE;
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 994ab67bc2dc..70eb5ed942d0 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -586,11 +586,13 @@ static void fastrpc_dma_buf_detatch(struct dma_buf *dmabuf,
 	kfree(a);
 }
 
-static void *fastrpc_vmap(struct dma_buf *dmabuf)
+static int fastrpc_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
 {
 	struct fastrpc_buf *buf = dmabuf->priv;
 
-	return buf->virt;
+	dma_buf_map_set_vaddr(map, buf->virt);
+
+	return 0;
 }
 
 static int fastrpc_mmap(struct dma_buf *dmabuf,
diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c
index 901e213daf40..ada570f35a41 100644
--- a/drivers/misc/habanalabs/common/command_buffer.c
+++ b/drivers/misc/habanalabs/common/command_buffer.c
@@ -142,11 +142,10 @@ static void cb_fini(struct hl_device *hdev, struct hl_cb *cb)
 {
 	if (cb->is_internal)
 		gen_pool_free(hdev->internal_cb_pool,
-				cb->kernel_address, cb->size);
+				(uintptr_t)cb->kernel_address, cb->size);
 	else
 		hdev->asic_funcs->asic_dma_free_coherent(hdev, cb->size,
-				(void *) (uintptr_t) cb->kernel_address,
-				cb->bus_address);
+				cb->kernel_address, cb->bus_address);
 
 	kfree(cb);
 }
@@ -230,7 +229,7 @@ static struct hl_cb *hl_cb_alloc(struct hl_device *hdev, u32 cb_size,
 		return NULL;
 	}
 
-	cb->kernel_address = (u64) (uintptr_t) p;
+	cb->kernel_address = p;
 	cb->size = cb_size;
 
 	return cb;
@@ -509,7 +508,7 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
 
 	vma->vm_private_data = cb;
 
-	rc = hdev->asic_funcs->cb_mmap(hdev, vma, (void *) cb->kernel_address,
+	rc = hdev->asic_funcs->cb_mmap(hdev, vma, cb->kernel_address,
 					cb->bus_address, cb->size);
 	if (rc) {
 		spin_lock(&cb->lock);
diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
index 20572224099a..783bbdcb1e61 100644
--- a/drivers/misc/habanalabs/common/device.c
+++ b/drivers/misc/habanalabs/common/device.c
@@ -231,16 +231,16 @@ delete_cdev_device:
 
 static void device_cdev_sysfs_del(struct hl_device *hdev)
 {
-	/* device_release() won't be called so must free devices explicitly */
-	if (!hdev->cdev_sysfs_created) {
-		kfree(hdev->dev_ctrl);
-		kfree(hdev->dev);
-		return;
-	}
+	if (!hdev->cdev_sysfs_created)
+		goto put_devices;
 
 	hl_sysfs_fini(hdev);
 	cdev_device_del(&hdev->cdev_ctrl, hdev->dev_ctrl);
 	cdev_device_del(&hdev->cdev, hdev->dev);
+
+put_devices:
+	put_device(hdev->dev);
+	put_device(hdev->dev_ctrl);
 }
 
 /*
@@ -1371,9 +1371,9 @@ sw_fini:
 early_fini:
 	device_early_fini(hdev);
 free_dev_ctrl:
-	kfree(hdev->dev_ctrl);
+	put_device(hdev->dev_ctrl);
 free_dev:
-	kfree(hdev->dev);
+	put_device(hdev->dev);
 out_disabled:
 	hdev->disabled = true;
 	if (add_cdev_sysfs_on_err)
diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
index 80d4d7385ffe..6ed974d2def0 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -452,7 +452,7 @@ struct hl_cb {
 	struct list_head	pool_list;
 	struct list_head	va_block_list;
 	u64			id;
-	u64			kernel_address;
+	void			*kernel_address;
 	dma_addr_t		bus_address;
 	u32			mmap_size;
 	u32			size;
@@ -515,7 +515,7 @@ struct hl_hw_queue {
 	struct hl_hw_sob	hw_sob[HL_RSVD_SOBS];
 	struct hl_cs_job	**shadow_queue;
 	enum hl_queue_type	queue_type;
-	u64			kernel_address;
+	void			*kernel_address;
 	dma_addr_t		bus_address;
 	u32			pi;
 	atomic_t		ci;
@@ -544,7 +544,7 @@ struct hl_hw_queue {
  */
 struct hl_cq {
 	struct hl_device	*hdev;
-	u64			kernel_address;
+	void			*kernel_address;
 	dma_addr_t		bus_address;
 	u32			cq_idx;
 	u32			hw_queue_id;
@@ -562,7 +562,7 @@ struct hl_cq {
  */
 struct hl_eq {
 	struct hl_device	*hdev;
-	u64			kernel_address;
+	void			*kernel_address;
 	dma_addr_t		bus_address;
 	u32			ci;
 };
@@ -757,7 +757,7 @@ struct hl_asic_funcs {
 	u32 (*get_dma_desc_list_size)(struct hl_device *hdev,
 					struct sg_table *sgt);
 	void (*add_end_of_cb_packets)(struct hl_device *hdev,
-					u64 kernel_address, u32 len,
+					void *kernel_address, u32 len,
 					u64 cq_addr, u32 cq_val, u32 msix_num,
 					bool eb);
 	void (*update_eq_ci)(struct hl_device *hdev, u32 val);
@@ -1382,13 +1382,13 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
 	for (;;) { \
 		/* Verify we read updates done by other cores or by device */ \
 		mb(); \
-		(val) = *((u32 *) (uintptr_t) (addr)); \
+		(val) = *((u32 *)(addr)); \
 		if (mem_written_by_device) \
 			(val) = le32_to_cpu(*(__le32 *) &(val)); \
 		if (cond) \
 			break; \
 		if (timeout_us && ktime_compare(ktime_get(), __timeout) > 0) { \
-			(val) = *((u32 *) (uintptr_t) (addr)); \
+			(val) = *((u32 *)(addr)); \
 			if (mem_written_by_device) \
 				(val) = le32_to_cpu(*(__le32 *) &(val)); \
 			break; \
diff --git a/drivers/misc/habanalabs/common/hw_queue.c b/drivers/misc/habanalabs/common/hw_queue.c
index 5e66c98fb0d3..250cf9cefc06 100644
--- a/drivers/misc/habanalabs/common/hw_queue.c
+++ b/drivers/misc/habanalabs/common/hw_queue.c
@@ -75,7 +75,7 @@ static void ext_and_hw_queue_submit_bd(struct hl_device *hdev,
 {
 	struct hl_bd *bd;
 
-	bd = (struct hl_bd *) (uintptr_t) q->kernel_address;
+	bd = q->kernel_address;
 	bd += hl_pi_2_offset(q->pi);
 	bd->ctl = cpu_to_le32(ctl);
 	bd->len = cpu_to_le32(len);
@@ -335,8 +335,7 @@ static void int_queue_schedule_job(struct hl_cs_job *job)
 	bd.len = cpu_to_le32(job->job_cb_size);
 	bd.ptr = cpu_to_le64((u64) (uintptr_t) job->user_cb);
 
-	pi = (__le64 *) (uintptr_t) (q->kernel_address +
-		((q->pi & (q->int_queue_len - 1)) * sizeof(bd)));
+	pi = q->kernel_address + (q->pi & (q->int_queue_len - 1)) * sizeof(bd);
 
 	q->pi++;
 	q->pi &= ((q->int_queue_len << 1) - 1);
@@ -630,7 +629,7 @@ static int ext_and_cpu_queue_init(struct hl_device *hdev, struct hl_hw_queue *q,
 	if (!p)
 		return -ENOMEM;
 
-	q->kernel_address = (u64) (uintptr_t) p;
+	q->kernel_address = p;
 
 	q->shadow_queue = kmalloc_array(HL_QUEUE_LENGTH,
 					sizeof(*q->shadow_queue),
@@ -653,11 +652,11 @@ free_queue:
 	if (is_cpu_queue)
 		hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev,
 					HL_QUEUE_SIZE_IN_BYTES,
-					(void *) (uintptr_t) q->kernel_address);
+					q->kernel_address);
 	else
 		hdev->asic_funcs->asic_dma_free_coherent(hdev,
 					HL_QUEUE_SIZE_IN_BYTES,
-					(void *) (uintptr_t) q->kernel_address,
+					q->kernel_address,
 					q->bus_address);
 
 	return rc;
@@ -676,7 +675,7 @@ static int int_queue_init(struct hl_device *hdev, struct hl_hw_queue *q)
 		return -EFAULT;
 	}
 
-	q->kernel_address = (u64) (uintptr_t) p;
+	q->kernel_address = p;
 	q->pi = 0;
 	atomic_set(&q->ci, 0);
 
@@ -704,7 +703,7 @@ static int hw_queue_init(struct hl_device *hdev, struct hl_hw_queue *q)
 	if (!p)
 		return -ENOMEM;
 
-	q->kernel_address = (u64) (uintptr_t) p;
+	q->kernel_address = p;
 
 	/* Make sure read/write pointers are initialized to start of queue */
 	atomic_set(&q->ci, 0);
@@ -839,11 +838,11 @@ static void queue_fini(struct hl_device *hdev, struct hl_hw_queue *q)
 	if (q->queue_type == QUEUE_TYPE_CPU)
 		hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev,
 					HL_QUEUE_SIZE_IN_BYTES,
-					(void *) (uintptr_t) q->kernel_address);
+					q->kernel_address);
 	else
 		hdev->asic_funcs->asic_dma_free_coherent(hdev,
 					HL_QUEUE_SIZE_IN_BYTES,
-					(void *) (uintptr_t) q->kernel_address,
+					q->kernel_address,
 					q->bus_address);
 }
 
diff --git a/drivers/misc/habanalabs/common/irq.c b/drivers/misc/habanalabs/common/irq.c
index d20e40a53d70..de53fb5f978a 100644
--- a/drivers/misc/habanalabs/common/irq.c
+++ b/drivers/misc/habanalabs/common/irq.c
@@ -90,7 +90,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg)
 		return IRQ_HANDLED;
 	}
 
-	cq_base = (struct hl_cq_entry *) (uintptr_t) cq->kernel_address;
+	cq_base = cq->kernel_address;
 
 	while (1) {
 		bool entry_ready = ((le32_to_cpu(cq_base[cq->ci].data) &
@@ -152,7 +152,7 @@ irqreturn_t hl_irq_handler_eq(int irq, void *arg)
 	struct hl_eq_entry *eq_base;
 	struct hl_eqe_work *handle_eqe_work;
 
-	eq_base = (struct hl_eq_entry *) (uintptr_t) eq->kernel_address;
+	eq_base = eq->kernel_address;
 
 	while (1) {
 		bool entry_ready =
@@ -221,7 +221,7 @@ int hl_cq_init(struct hl_device *hdev, struct hl_cq *q, u32 hw_queue_id)
 		return -ENOMEM;
 
 	q->hdev = hdev;
-	q->kernel_address = (u64) (uintptr_t) p;
+	q->kernel_address = p;
 	q->hw_queue_id = hw_queue_id;
 	q->ci = 0;
 	q->pi = 0;
@@ -242,7 +242,8 @@ int hl_cq_init(struct hl_device *hdev, struct hl_cq *q, u32 hw_queue_id)
 void hl_cq_fini(struct hl_device *hdev, struct hl_cq *q)
 {
 	hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_CQ_SIZE_IN_BYTES,
-			(void *) (uintptr_t) q->kernel_address, q->bus_address);
+						 q->kernel_address,
+						 q->bus_address);
 }
 
 void hl_cq_reset(struct hl_device *hdev, struct hl_cq *q)
@@ -259,7 +260,7 @@ void hl_cq_reset(struct hl_device *hdev, struct hl_cq *q)
 	 * when the device is operational again
 	 */
 
-	memset((void *) (uintptr_t) q->kernel_address, 0, HL_CQ_SIZE_IN_BYTES);
+	memset(q->kernel_address, 0, HL_CQ_SIZE_IN_BYTES);
 }
 
 /**
@@ -282,7 +283,7 @@ int hl_eq_init(struct hl_device *hdev, struct hl_eq *q)
 		return -ENOMEM;
 
 	q->hdev = hdev;
-	q->kernel_address = (u64) (uintptr_t) p;
+	q->kernel_address = p;
 	q->ci = 0;
 
 	return 0;
@@ -302,7 +303,7 @@ void hl_eq_fini(struct hl_device *hdev, struct hl_eq *q)
 
 	hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev,
 					HL_EQ_SIZE_IN_BYTES,
-					(void *) (uintptr_t) q->kernel_address);
+					q->kernel_address);
 }
 
 void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q)
@@ -316,5 +317,5 @@ void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q)
 	 * when the device is operational again
 	 */
 
-	memset((void *) (uintptr_t) q->kernel_address, 0, HL_EQ_SIZE_IN_BYTES);
+	memset(q->kernel_address, 0, HL_EQ_SIZE_IN_BYTES);
 }
diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c
index 84227819e4d1..bfe223abf142 100644
--- a/drivers/misc/habanalabs/common/memory.c
+++ b/drivers/misc/habanalabs/common/memory.c
@@ -1626,6 +1626,7 @@ static int vm_ctx_init_with_ranges(struct hl_ctx *ctx,
 			goto host_hpage_range_err;
 		}
 	} else {
+		kfree(ctx->host_huge_va_range);
 		ctx->host_huge_va_range = ctx->host_va_range;
 	}
 
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 5f65a1691551..7ea6b4368a91 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -680,8 +680,7 @@ static int _gaudi_init_tpc_mem(struct hl_device *hdev,
 	if (!cb)
 		return -EFAULT;
 
-	init_tpc_mem_pkt = (struct packet_lin_dma *) (uintptr_t)
-					cb->kernel_address;
+	init_tpc_mem_pkt = cb->kernel_address;
 	cb_size = sizeof(*init_tpc_mem_pkt);
 	memset(init_tpc_mem_pkt, 0, cb_size);
 
@@ -3811,8 +3810,7 @@ static int gaudi_validate_cb(struct hl_device *hdev,
 		u16 pkt_size;
 		struct gaudi_packet *user_pkt;
 
-		user_pkt = (struct gaudi_packet *) (uintptr_t)
-			(parser->user_cb->kernel_address + cb_parsed_length);
+		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
 
 		pkt_id = (enum packet_id) (
 				(le64_to_cpu(user_pkt->header) &
@@ -4035,11 +4033,9 @@ static int gaudi_patch_cb(struct hl_device *hdev,
 		u32 new_pkt_size = 0;
 		struct gaudi_packet *user_pkt, *kernel_pkt;
 
-		user_pkt = (struct gaudi_packet *) (uintptr_t)
-			(parser->user_cb->kernel_address + cb_parsed_length);
-		kernel_pkt = (struct gaudi_packet *) (uintptr_t)
-			(parser->patched_cb->kernel_address +
-					cb_patched_cur_length);
+		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
+		kernel_pkt = parser->patched_cb->kernel_address +
+					cb_patched_cur_length;
 
 		pkt_id = (enum packet_id) (
 				(le64_to_cpu(user_pkt->header) &
@@ -4155,8 +4151,8 @@ static int gaudi_parse_cb_mmu(struct hl_device *hdev,
 	 * The check that parser->user_cb_size <= parser->user_cb->size was done
 	 * in validate_queue_index().
 	 */
-	memcpy((void *) (uintptr_t) parser->patched_cb->kernel_address,
-		(void *) (uintptr_t) parser->user_cb->kernel_address,
+	memcpy(parser->patched_cb->kernel_address,
+		parser->user_cb->kernel_address,
 		parser->user_cb_size);
 
 	patched_cb_size = parser->patched_cb_size;
@@ -4290,7 +4286,7 @@ static int gaudi_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser)
 }
 
 static void gaudi_add_end_of_cb_packets(struct hl_device *hdev,
-					u64 kernel_address, u32 len,
+					void *kernel_address, u32 len,
 					u64 cq_addr, u32 cq_val, u32 msi_vec,
 					bool eb)
 {
@@ -4298,8 +4294,7 @@ static void gaudi_add_end_of_cb_packets(struct hl_device *hdev,
 	struct packet_msg_prot *cq_pkt;
 	u32 tmp;
 
-	cq_pkt = (struct packet_msg_prot *) (uintptr_t)
-		(kernel_address + len - (sizeof(struct packet_msg_prot) * 2));
+	cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2);
 
 	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
 	tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1);
@@ -4342,7 +4337,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr,
 	if (!cb)
 		return -EFAULT;
 
-	lin_dma_pkt = (struct packet_lin_dma *) (uintptr_t) cb->kernel_address;
+	lin_dma_pkt = cb->kernel_address;
 	memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt));
 	cb_size = sizeof(*lin_dma_pkt);
 
@@ -4747,7 +4742,7 @@ static void gaudi_write_pte(struct hl_device *hdev, u64 addr, u64 val)
 			(addr - gaudi->hbm_bar_cur_addr));
 }
 
-static void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid)
+void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid)
 {
 	/* mask to zero the MMBP and ASID bits */
 	WREG32_AND(reg, ~0x7FF);
@@ -4915,9 +4910,6 @@ static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid)
 	gaudi_mmu_prepare_reg(hdev, mmMME2_ACC_WBC, asid);
 	gaudi_mmu_prepare_reg(hdev, mmMME3_ACC_WBC, asid);
 
-	gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER, asid);
-	gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER, asid);
-
 	hdev->asic_funcs->set_clock_gating(hdev);
 
 	mutex_unlock(&gaudi->clk_gate_mutex);
@@ -4954,8 +4946,8 @@ static int gaudi_send_job_on_qman0(struct hl_device *hdev,
 
 	cb = job->patched_cb;
 
-	fence_pkt = (struct packet_msg_prot *) (uintptr_t) (cb->kernel_address +
-			job->job_cb_size - sizeof(struct packet_msg_prot));
+	fence_pkt = cb->kernel_address +
+			job->job_cb_size - sizeof(struct packet_msg_prot);
 
 	tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT);
 	tmp |= FIELD_PREP(GAUDI_PKT_CTL_EB_MASK, 1);
@@ -5444,6 +5436,8 @@ static void gaudi_handle_ecc_event(struct hl_device *hdev, u16 event_type,
 		params.num_memories = 33;
 		params.derr = true;
 		params.disable_clock_gating = true;
+		extract_info_from_fw = false;
+		break;
 	default:
 		return;
 	}
@@ -6386,7 +6380,7 @@ static void gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id)
 	struct packet_msg_short *pkt;
 	u32 value, ctl;
 
-	pkt = (struct packet_msg_short *) (uintptr_t) cb->kernel_address;
+	pkt = cb->kernel_address;
 	memset(pkt, 0, sizeof(*pkt));
 
 	/* Inc by 1, Mode ADD */
@@ -6478,7 +6472,7 @@ static void gaudi_gen_wait_cb(struct hl_device *hdev, void *data, u16 sob_id,
 			u16 sob_val, u16 mon_id, u32 q_idx)
 {
 	struct hl_cb *cb = (struct hl_cb *) data;
-	void *buf = (void *) (uintptr_t) cb->kernel_address;
+	void *buf = cb->kernel_address;
 	u64 monitor_base, fence_addr = 0;
 	u32 size = 0;
 	u16 msg_addr_offset;
diff --git a/drivers/misc/habanalabs/gaudi/gaudiP.h b/drivers/misc/habanalabs/gaudi/gaudiP.h
index 83ad2b0a3a61..8eb598db81b2 100644
--- a/drivers/misc/habanalabs/gaudi/gaudiP.h
+++ b/drivers/misc/habanalabs/gaudi/gaudiP.h
@@ -271,5 +271,6 @@ void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq);
 int gaudi_debug_coresight(struct hl_device *hdev, void *data);
 void gaudi_halt_coresight(struct hl_device *hdev);
 int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk);
+void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid);
 
 #endif /* GAUDIP_H_ */
diff --git a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
index 881531d4d9da..3d2b0f0f4650 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
@@ -623,6 +623,11 @@ static int gaudi_config_etr(struct hl_device *hdev,
 			return -EINVAL;
 		}
 
+		gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER,
+						hdev->compute_ctx->asid);
+		gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER,
+						hdev->compute_ctx->asid);
+
 		msb = upper_32_bits(input->buffer_address) >> 8;
 		msb &= PSOC_GLOBAL_CONF_TRACE_ADDR_MSB_MASK;
 		WREG32(mmPSOC_GLOBAL_CONF_TRACE_ADDR, msb);
diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c
index 5db52064ed9e..235d47b2420f 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -2882,8 +2882,8 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job)
 
 	cb = job->patched_cb;
 
-	fence_pkt = (struct packet_msg_prot *) (uintptr_t) (cb->kernel_address +
-			job->job_cb_size - sizeof(struct packet_msg_prot));
+	fence_pkt = cb->kernel_address +
+			job->job_cb_size - sizeof(struct packet_msg_prot);
 
 	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
 			(1 << GOYA_PKT_CTL_EB_SHIFT) |
@@ -3475,8 +3475,7 @@ static int goya_validate_cb(struct hl_device *hdev,
 		u16 pkt_size;
 		struct goya_packet *user_pkt;
 
-		user_pkt = (struct goya_packet *) (uintptr_t)
-			(parser->user_cb->kernel_address + cb_parsed_length);
+		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
 
 		pkt_id = (enum packet_id) (
 				(le64_to_cpu(user_pkt->header) &
@@ -3713,11 +3712,9 @@ static int goya_patch_cb(struct hl_device *hdev,
 		u32 new_pkt_size = 0;
 		struct goya_packet *user_pkt, *kernel_pkt;
 
-		user_pkt = (struct goya_packet *) (uintptr_t)
-			(parser->user_cb->kernel_address + cb_parsed_length);
-		kernel_pkt = (struct goya_packet *) (uintptr_t)
-			(parser->patched_cb->kernel_address +
-					cb_patched_cur_length);
+		user_pkt = parser->user_cb->kernel_address + cb_parsed_length;
+		kernel_pkt = parser->patched_cb->kernel_address +
+					cb_patched_cur_length;
 
 		pkt_id = (enum packet_id) (
 				(le64_to_cpu(user_pkt->header) &
@@ -3841,8 +3838,8 @@ static int goya_parse_cb_mmu(struct hl_device *hdev,
 	 * The check that parser->user_cb_size <= parser->user_cb->size was done
 	 * in validate_queue_index().
 	 */
-	memcpy((void *) (uintptr_t) parser->patched_cb->kernel_address,
-		(void *) (uintptr_t) parser->user_cb->kernel_address,
+	memcpy(parser->patched_cb->kernel_address,
+		parser->user_cb->kernel_address,
 		parser->user_cb_size);
 
 	patched_cb_size = parser->patched_cb_size;
@@ -3974,15 +3971,14 @@ int goya_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser)
 		return goya_parse_cb_no_mmu(hdev, parser);
 }
 
-void goya_add_end_of_cb_packets(struct hl_device *hdev, u64 kernel_address,
+void goya_add_end_of_cb_packets(struct hl_device *hdev, void *kernel_address,
 				u32 len, u64 cq_addr, u32 cq_val, u32 msix_vec,
 				bool eb)
 {
 	struct packet_msg_prot *cq_pkt;
 	u32 tmp;
 
-	cq_pkt = (struct packet_msg_prot *) (uintptr_t)
-		(kernel_address + len - (sizeof(struct packet_msg_prot) * 2));
+	cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2);
 
 	tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) |
 			(1 << GOYA_PKT_CTL_EB_SHIFT) |
@@ -4746,7 +4742,7 @@ static int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size,
 	if (!cb)
 		return -ENOMEM;
 
-	lin_dma_pkt = (struct packet_lin_dma *) (uintptr_t) cb->kernel_address;
+	lin_dma_pkt = cb->kernel_address;
 
 	do {
 		memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt));
diff --git a/drivers/misc/habanalabs/goya/goyaP.h b/drivers/misc/habanalabs/goya/goyaP.h
index 09b4006d4dc3..def86c75e035 100644
--- a/drivers/misc/habanalabs/goya/goyaP.h
+++ b/drivers/misc/habanalabs/goya/goyaP.h
@@ -217,7 +217,7 @@ int goya_resume(struct hl_device *hdev);
 void goya_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entry);
 void *goya_get_events_stat(struct hl_device *hdev, bool aggregate, u32 *size);
 
-void goya_add_end_of_cb_packets(struct hl_device *hdev, u64 kernel_address,
+void goya_add_end_of_cb_packets(struct hl_device *hdev, void *kernel_address,
 				u32 len, u64 cq_addr, u32 cq_val, u32 msix_vec,
 				bool eb);
 int goya_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser);
diff --git a/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h b/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h
index f395721060bd..46aed13f16b1 100644
--- a/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h
+++ b/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h
@@ -421,7 +421,6 @@ enum axi_id {
 
 #define QM_ARB_ERR_MSG_EN_MASK		(\
 					QM_ARB_ERR_MSG_EN_CHOISE_OVF_MASK |\
-					QM_ARB_ERR_MSG_EN_CHOISE_WDT_MASK |\
 					QM_ARB_ERR_MSG_EN_AXI_LBW_ERR_MASK)
 
 #define PCIE_AUX_FLR_CTRL_HW_CTRL_MASK                               0x1
diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile
index c70b3822013f..1c4c7aca0026 100644
--- a/drivers/misc/lkdtm/Makefile
+++ b/drivers/misc/lkdtm/Makefile
@@ -11,6 +11,7 @@ lkdtm-$(CONFIG_LKDTM)		+= usercopy.o
 lkdtm-$(CONFIG_LKDTM)		+= stackleak.o
 lkdtm-$(CONFIG_LKDTM)		+= cfi.o
 
+KASAN_SANITIZE_rodata.o		:= n
 KASAN_SANITIZE_stackleak.o	:= n
 KCOV_INSTRUMENT_rodata.o	:= n
 
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index c06581ffa7bd..f5fd5b786607 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -46,14 +46,4 @@ config INTEL_MEI_TXE
 	  Supported SoCs:
 	  Intel Bay Trail
 
-config INTEL_MEI_VIRTIO
-	tristate "Intel MEI interface emulation with virtio framework"
-	select INTEL_MEI
-	depends on X86 && PCI && VIRTIO_PCI
-	help
-	  This module implements mei hw emulation over virtio transport.
-	  The module will be called mei_virtio.
-	  Enable this if your virtual machine supports virtual mei
-	  device over virtio.
-
 source "drivers/misc/mei/hdcp/Kconfig"
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 52aefaab5c1b..f1c76f7ee804 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -22,9 +22,6 @@ obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
 mei-txe-objs := pci-txe.o
 mei-txe-objs += hw-txe.o
 
-obj-$(CONFIG_INTEL_MEI_VIRTIO) += mei-virtio.o
-mei-virtio-objs := hw-virtio.o
-
 mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
 CFLAGS_mei-trace.o = -I$(src)
 
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 64143d4ec758..9e08a9843bba 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -182,11 +182,11 @@ static inline u8 mei_cl_me_id(const struct mei_cl *cl)
  *
  * @cl: host client
  *
- * Return: mtu
+ * Return: mtu or 0 if client is not connected
  */
 static inline size_t mei_cl_mtu(const struct mei_cl *cl)
 {
-	return cl->me_cl->props.max_msg_length;
+	return cl->me_cl ? cl->me_cl->props.max_msg_length : 0;
 }
 
 /**
diff --git a/drivers/misc/mei/hw-virtio.c b/drivers/misc/mei/hw-virtio.c
deleted file mode 100644
index 899dc1c5e7ca..000000000000
--- a/drivers/misc/mei/hw-virtio.c
+++ /dev/null
@@ -1,874 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2018-2020, Intel Corporation.
- */
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/pm_runtime.h>
-#include <linux/scatterlist.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/virtio.h>
-#include <linux/virtio_config.h>
-#include <linux/virtio_ids.h>
-#include <linux/atomic.h>
-
-#include "mei_dev.h"
-#include "hbm.h"
-#include "client.h"
-
-#define MEI_VIRTIO_RPM_TIMEOUT 500
-/* ACRN virtio device types */
-#ifndef VIRTIO_ID_MEI
-#define VIRTIO_ID_MEI 0xFFFE /* virtio mei */
-#endif
-
-/**
- * struct mei_virtio_cfg - settings passed from the virtio backend
- * @buf_depth: read buffer depth in slots (4bytes)
- * @hw_ready: hw is ready for operation
- * @host_reset: synchronize reset with virtio backend
- * @reserved: reserved for alignment
- * @fw_status: FW status
- */
-struct mei_virtio_cfg {
-	u32 buf_depth;
-	u8 hw_ready;
-	u8 host_reset;
-	u8 reserved[2];
-	u32 fw_status[MEI_FW_STATUS_MAX];
-} __packed;
-
-struct mei_virtio_hw {
-	struct mei_device mdev;
-	char name[32];
-
-	struct virtqueue *in;
-	struct virtqueue *out;
-
-	bool host_ready;
-	struct work_struct intr_handler;
-
-	u32 *recv_buf;
-	u8 recv_rdy;
-	size_t recv_sz;
-	u32 recv_idx;
-	u32 recv_len;
-
-	/* send buffer */
-	atomic_t hbuf_ready;
-	const void *send_hdr;
-	const void *send_buf;
-
-	struct mei_virtio_cfg cfg;
-};
-
-#define to_virtio_hw(_dev) container_of(_dev, struct mei_virtio_hw, mdev)
-
-/**
- * mei_virtio_fw_status() - read status register of mei
- * @dev: mei device
- * @fw_status: fw status register values
- *
- * Return: always 0
- */
-static int mei_virtio_fw_status(struct mei_device *dev,
-				struct mei_fw_status *fw_status)
-{
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	fw_status->count = MEI_FW_STATUS_MAX;
-	virtio_cread_bytes(vdev, offsetof(struct mei_virtio_cfg, fw_status),
-			   fw_status->status, sizeof(fw_status->status));
-	return 0;
-}
-
-/**
- * mei_virtio_pg_state() - translate internal pg state
- *   to the mei power gating state
- *   There is no power management in ACRN mode always return OFF
- * @dev: mei device
- *
- * Return:
- * * MEI_PG_OFF - if aliveness is on (always)
- * * MEI_PG_ON  - (never)
- */
-static inline enum mei_pg_state mei_virtio_pg_state(struct mei_device *dev)
-{
-	return MEI_PG_OFF;
-}
-
-/**
- * mei_virtio_hw_config() - configure hw dependent settings
- *
- * @dev: mei device
- *
- * Return: always 0
- */
-static int mei_virtio_hw_config(struct mei_device *dev)
-{
-	return 0;
-}
-
-/**
- * mei_virtio_hbuf_empty_slots() - counts write empty slots.
- * @dev: the device structure
- *
- * Return: always return frontend buf size if buffer is ready, 0 otherwise
- */
-static int mei_virtio_hbuf_empty_slots(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	return (atomic_read(&hw->hbuf_ready) == 1) ? hw->cfg.buf_depth : 0;
-}
-
-/**
- * mei_virtio_hbuf_is_ready() - checks if write buffer is ready
- * @dev: the device structure
- *
- * Return: true if hbuf is ready
- */
-static bool mei_virtio_hbuf_is_ready(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	return atomic_read(&hw->hbuf_ready) == 1;
-}
-
-/**
- * mei_virtio_hbuf_max_depth() - returns depth of FE write buffer.
- * @dev: the device structure
- *
- * Return: size of frontend write buffer in bytes
- */
-static u32 mei_virtio_hbuf_depth(const struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	return hw->cfg.buf_depth;
-}
-
-/**
- * mei_virtio_intr_clear() - clear and stop interrupts
- * @dev: the device structure
- */
-static void mei_virtio_intr_clear(struct mei_device *dev)
-{
-	/*
-	 * In our virtio solution, there are two types of interrupts,
-	 * vq interrupt and config change interrupt.
-	 *   1) start/reset rely on virtio config changed interrupt;
-	 *   2) send/recv rely on virtio virtqueue interrupts.
-	 * They are all virtual interrupts. So, we don't have corresponding
-	 * operation to do here.
-	 */
-}
-
-/**
- * mei_virtio_intr_enable() - enables mei BE virtqueues callbacks
- * @dev: the device structure
- */
-static void mei_virtio_intr_enable(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	virtio_config_enable(vdev);
-
-	virtqueue_enable_cb(hw->in);
-	virtqueue_enable_cb(hw->out);
-}
-
-/**
- * mei_virtio_intr_disable() - disables mei BE virtqueues callbacks
- *
- * @dev: the device structure
- */
-static void mei_virtio_intr_disable(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	virtio_config_disable(vdev);
-
-	virtqueue_disable_cb(hw->in);
-	virtqueue_disable_cb(hw->out);
-}
-
-/**
- * mei_virtio_synchronize_irq() - wait for pending IRQ handlers for all
- *     virtqueue
- * @dev: the device structure
- */
-static void mei_virtio_synchronize_irq(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	/*
-	 * Now, all IRQ handlers are converted to workqueue.
-	 * Change synchronize irq to flush this work.
-	 */
-	flush_work(&hw->intr_handler);
-}
-
-static void mei_virtio_free_outbufs(struct mei_virtio_hw *hw)
-{
-	kfree(hw->send_hdr);
-	kfree(hw->send_buf);
-	hw->send_hdr = NULL;
-	hw->send_buf = NULL;
-}
-
-/**
- * mei_virtio_write_message() - writes a message to mei virtio back-end service.
- * @dev: the device structure
- * @hdr: mei header of message
- * @hdr_len: header length
- * @data: message payload will be written
- * @data_len: message payload length
- *
- * Return:
- * *  0: on success
- * * -EIO: if write has failed
- * * -ENOMEM: on memory allocation failure
- */
-static int mei_virtio_write_message(struct mei_device *dev,
-				    const void *hdr, size_t hdr_len,
-				    const void *data, size_t data_len)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct scatterlist sg[2];
-	const void *hbuf, *dbuf;
-	int ret;
-
-	if (WARN_ON(!atomic_add_unless(&hw->hbuf_ready, -1, 0)))
-		return -EIO;
-
-	hbuf = kmemdup(hdr, hdr_len, GFP_KERNEL);
-	hw->send_hdr = hbuf;
-
-	dbuf = kmemdup(data, data_len, GFP_KERNEL);
-	hw->send_buf = dbuf;
-
-	if (!hbuf || !dbuf) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
-	sg_init_table(sg, 2);
-	sg_set_buf(&sg[0], hbuf, hdr_len);
-	sg_set_buf(&sg[1], dbuf, data_len);
-
-	ret = virtqueue_add_outbuf(hw->out, sg, 2, hw, GFP_KERNEL);
-	if (ret) {
-		dev_err(dev->dev, "failed to add outbuf\n");
-		goto fail;
-	}
-
-	virtqueue_kick(hw->out);
-	return 0;
-fail:
-
-	mei_virtio_free_outbufs(hw);
-
-	return ret;
-}
-
-/**
- * mei_virtio_count_full_read_slots() - counts read full slots.
- * @dev: the device structure
- *
- * Return: -EOVERFLOW if overflow, otherwise filled slots count
- */
-static int mei_virtio_count_full_read_slots(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	if (hw->recv_idx > hw->recv_len)
-		return -EOVERFLOW;
-
-	return hw->recv_len - hw->recv_idx;
-}
-
-/**
- * mei_virtio_read_hdr() - Reads 32bit dword from mei virtio receive buffer
- *
- * @dev: the device structure
- *
- * Return: 32bit dword of receive buffer (u32)
- */
-static inline u32 mei_virtio_read_hdr(const struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	WARN_ON(hw->cfg.buf_depth < hw->recv_idx + 1);
-
-	return hw->recv_buf[hw->recv_idx++];
-}
-
-static int mei_virtio_read(struct mei_device *dev, unsigned char *buffer,
-			   unsigned long len)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	u32 slots = mei_data2slots(len);
-
-	if (WARN_ON(hw->cfg.buf_depth < hw->recv_idx + slots))
-		return -EOVERFLOW;
-
-	/*
-	 * Assumption: There is only one MEI message in recv_buf each time.
-	 * Backend service need follow this rule too.
-	 */
-	memcpy(buffer, hw->recv_buf + hw->recv_idx, len);
-	hw->recv_idx += slots;
-
-	return 0;
-}
-
-static bool mei_virtio_pg_is_enabled(struct mei_device *dev)
-{
-	return false;
-}
-
-static bool mei_virtio_pg_in_transition(struct mei_device *dev)
-{
-	return false;
-}
-
-static void mei_virtio_add_recv_buf(struct mei_virtio_hw *hw)
-{
-	struct scatterlist sg;
-
-	if (hw->recv_rdy) /* not needed */
-		return;
-
-	/* refill the recv_buf to IN virtqueue to get next message */
-	sg_init_one(&sg, hw->recv_buf, mei_slots2data(hw->cfg.buf_depth));
-	hw->recv_len = 0;
-	hw->recv_idx = 0;
-	hw->recv_rdy = 1;
-	virtqueue_add_inbuf(hw->in, &sg, 1, hw->recv_buf, GFP_KERNEL);
-	virtqueue_kick(hw->in);
-}
-
-/**
- * mei_virtio_hw_is_ready() - check whether the BE(hw) has turned ready
- * @dev: mei device
- * Return: bool
- */
-static bool mei_virtio_hw_is_ready(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	virtio_cread(vdev, struct mei_virtio_cfg,
-		     hw_ready, &hw->cfg.hw_ready);
-
-	dev_dbg(dev->dev, "hw ready %d\n", hw->cfg.hw_ready);
-
-	return hw->cfg.hw_ready;
-}
-
-/**
- * mei_virtio_hw_reset - resets virtio hw.
- *
- * @dev: the device structure
- * @intr_enable: virtio use data/config callbacks
- *
- * Return: 0 on success an error code otherwise
- */
-static int mei_virtio_hw_reset(struct mei_device *dev, bool intr_enable)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	dev_dbg(dev->dev, "hw reset\n");
-
-	dev->recvd_hw_ready = false;
-	hw->host_ready = false;
-	atomic_set(&hw->hbuf_ready, 0);
-	hw->recv_len = 0;
-	hw->recv_idx = 0;
-
-	hw->cfg.host_reset = 1;
-	virtio_cwrite(vdev, struct mei_virtio_cfg,
-		      host_reset, &hw->cfg.host_reset);
-
-	mei_virtio_hw_is_ready(dev);
-
-	if (intr_enable)
-		mei_virtio_intr_enable(dev);
-
-	return 0;
-}
-
-/**
- * mei_virtio_hw_reset_release() - release device from the reset
- * @dev: the device structure
- */
-static void mei_virtio_hw_reset_release(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	struct virtio_device *vdev = dev_to_virtio(dev->dev);
-
-	dev_dbg(dev->dev, "hw reset release\n");
-	hw->cfg.host_reset = 0;
-	virtio_cwrite(vdev, struct mei_virtio_cfg,
-		      host_reset, &hw->cfg.host_reset);
-}
-
-/**
- * mei_virtio_hw_ready_wait() - wait until the virtio(hw) has turned ready
- *  or timeout is reached
- * @dev: mei device
- *
- * Return: 0 on success, error otherwise
- */
-static int mei_virtio_hw_ready_wait(struct mei_device *dev)
-{
-	mutex_unlock(&dev->device_lock);
-	wait_event_timeout(dev->wait_hw_ready,
-			   dev->recvd_hw_ready,
-			   mei_secs_to_jiffies(MEI_HW_READY_TIMEOUT));
-	mutex_lock(&dev->device_lock);
-	if (!dev->recvd_hw_ready) {
-		dev_err(dev->dev, "wait hw ready failed\n");
-		return -ETIMEDOUT;
-	}
-
-	dev->recvd_hw_ready = false;
-	return 0;
-}
-
-/**
- * mei_virtio_hw_start() - hw start routine
- * @dev: mei device
- *
- * Return: 0 on success, error otherwise
- */
-static int mei_virtio_hw_start(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-	int ret;
-
-	dev_dbg(dev->dev, "hw start\n");
-	mei_virtio_hw_reset_release(dev);
-
-	ret = mei_virtio_hw_ready_wait(dev);
-	if (ret)
-		return ret;
-
-	mei_virtio_add_recv_buf(hw);
-	atomic_set(&hw->hbuf_ready, 1);
-	dev_dbg(dev->dev, "hw is ready\n");
-	hw->host_ready = true;
-
-	return 0;
-}
-
-/**
- * mei_virtio_host_is_ready() - check whether the FE has turned ready
- * @dev: mei device
- *
- * Return: bool
- */
-static bool mei_virtio_host_is_ready(struct mei_device *dev)
-{
-	struct mei_virtio_hw *hw = to_virtio_hw(dev);
-
-	dev_dbg(dev->dev, "host ready %d\n", hw->host_ready);
-
-	return hw->host_ready;
-}
-
-/**
- * mei_virtio_data_in() - The callback of recv virtqueue of virtio mei
- * @vq: receiving virtqueue
- */
-static void mei_virtio_data_in(struct virtqueue *vq)
-{
-	struct mei_virtio_hw *hw = vq->vdev->priv;
-
-	/* disable interrupts (enabled again from in the interrupt worker) */
-	virtqueue_disable_cb(hw->in);
-
-	schedule_work(&hw->intr_handler);
-}
-
-/**
- * mei_virtio_data_out() - The callback of send virtqueue of virtio mei
- * @vq: transmitting virtqueue
- */
-static void mei_virtio_data_out(struct virtqueue *vq)
-{
-	struct mei_virtio_hw *hw = vq->vdev->priv;
-
-	schedule_work(&hw->intr_handler);
-}
-
-static void mei_virtio_intr_handler(struct work_struct *work)
-{
-	struct mei_virtio_hw *hw =
-		container_of(work, struct mei_virtio_hw, intr_handler);
-	struct mei_device *dev = &hw->mdev;
-	LIST_HEAD(complete_list);
-	s32 slots;
-	int rets = 0;
-	void *data;
-	unsigned int len;
-
-	mutex_lock(&dev->device_lock);
-
-	if (dev->dev_state == MEI_DEV_DISABLED) {
-		dev_warn(dev->dev, "Interrupt in disabled state.\n");
-		mei_virtio_intr_disable(dev);
-		goto end;
-	}
-
-	/* check if ME wants a reset */
-	if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) {
-		dev_warn(dev->dev, "BE service not ready: resetting.\n");
-		schedule_work(&dev->reset_work);
-		goto end;
-	}
-
-	/* check if we need to start the dev */
-	if (!mei_host_is_ready(dev)) {
-		if (mei_hw_is_ready(dev)) {
-			dev_dbg(dev->dev, "we need to start the dev.\n");
-			dev->recvd_hw_ready = true;
-			wake_up(&dev->wait_hw_ready);
-		} else {
-			dev_warn(dev->dev, "Spurious Interrupt\n");
-		}
-		goto end;
-	}
-
-	/* read */
-	if (hw->recv_rdy) {
-		data = virtqueue_get_buf(hw->in, &len);
-		if (!data || !len) {
-			dev_dbg(dev->dev, "No data %d", len);
-		} else {
-			dev_dbg(dev->dev, "data_in %d\n", len);
-			WARN_ON(data != hw->recv_buf);
-			hw->recv_len = mei_data2slots(len);
-			hw->recv_rdy = 0;
-		}
-	}
-
-	/* write */
-	if (!atomic_read(&hw->hbuf_ready)) {
-		if (!virtqueue_get_buf(hw->out, &len)) {
-			dev_warn(dev->dev, "Failed to getbuf\n");
-		} else {
-			mei_virtio_free_outbufs(hw);
-			atomic_inc(&hw->hbuf_ready);
-		}
-	}
-
-	/* check slots available for reading */
-	slots = mei_count_full_read_slots(dev);
-	while (slots > 0) {
-		dev_dbg(dev->dev, "slots to read = %08x\n", slots);
-		rets = mei_irq_read_handler(dev, &complete_list, &slots);
-
-		if (rets &&
-		    (dev->dev_state != MEI_DEV_RESETTING &&
-		     dev->dev_state != MEI_DEV_POWER_DOWN)) {
-			dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n",
-				rets);
-			schedule_work(&dev->reset_work);
-			goto end;
-		}
-	}
-
-	dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
-
-	mei_irq_write_handler(dev, &complete_list);
-
-	dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
-
-	mei_irq_compl_handler(dev, &complete_list);
-
-	mei_virtio_add_recv_buf(hw);
-
-end:
-	if (dev->dev_state != MEI_DEV_DISABLED) {
-		if (!virtqueue_enable_cb(hw->in))
-			schedule_work(&hw->intr_handler);
-	}
-
-	mutex_unlock(&dev->device_lock);
-}
-
-static void mei_virtio_config_changed(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw = vdev->priv;
-	struct mei_device *dev = &hw->mdev;
-
-	virtio_cread(vdev, struct mei_virtio_cfg,
-		     hw_ready, &hw->cfg.hw_ready);
-
-	if (dev->dev_state == MEI_DEV_DISABLED) {
-		dev_dbg(dev->dev, "disabled state don't start\n");
-		return;
-	}
-
-	/* Run intr handler once to handle reset notify */
-	schedule_work(&hw->intr_handler);
-}
-
-static void mei_virtio_remove_vqs(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw = vdev->priv;
-
-	virtqueue_detach_unused_buf(hw->in);
-	hw->recv_len = 0;
-	hw->recv_idx = 0;
-	hw->recv_rdy = 0;
-
-	virtqueue_detach_unused_buf(hw->out);
-
-	mei_virtio_free_outbufs(hw);
-
-	vdev->config->del_vqs(vdev);
-}
-
-/*
- * There are two virtqueues, one is for send and another is for recv.
- */
-static int mei_virtio_init_vqs(struct mei_virtio_hw *hw,
-			       struct virtio_device *vdev)
-{
-	struct virtqueue *vqs[2];
-
-	vq_callback_t *cbs[] = {
-		mei_virtio_data_in,
-		mei_virtio_data_out,
-	};
-	static const char * const names[] = {
-		"in",
-		"out",
-	};
-	int ret;
-
-	ret = virtio_find_vqs(vdev, 2, vqs, cbs, names, NULL);
-	if (ret)
-		return ret;
-
-	hw->in = vqs[0];
-	hw->out = vqs[1];
-
-	return 0;
-}
-
-static const struct mei_hw_ops mei_virtio_ops = {
-	.fw_status = mei_virtio_fw_status,
-	.pg_state  = mei_virtio_pg_state,
-
-	.host_is_ready = mei_virtio_host_is_ready,
-
-	.hw_is_ready = mei_virtio_hw_is_ready,
-	.hw_reset = mei_virtio_hw_reset,
-	.hw_config = mei_virtio_hw_config,
-	.hw_start = mei_virtio_hw_start,
-
-	.pg_in_transition = mei_virtio_pg_in_transition,
-	.pg_is_enabled = mei_virtio_pg_is_enabled,
-
-	.intr_clear = mei_virtio_intr_clear,
-	.intr_enable = mei_virtio_intr_enable,
-	.intr_disable = mei_virtio_intr_disable,
-	.synchronize_irq = mei_virtio_synchronize_irq,
-
-	.hbuf_free_slots = mei_virtio_hbuf_empty_slots,
-	.hbuf_is_ready = mei_virtio_hbuf_is_ready,
-	.hbuf_depth = mei_virtio_hbuf_depth,
-
-	.write = mei_virtio_write_message,
-
-	.rdbuf_full_slots = mei_virtio_count_full_read_slots,
-	.read_hdr = mei_virtio_read_hdr,
-	.read = mei_virtio_read,
-};
-
-static int mei_virtio_probe(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw;
-	int ret;
-
-	hw = devm_kzalloc(&vdev->dev, sizeof(*hw), GFP_KERNEL);
-	if (!hw)
-		return -ENOMEM;
-
-	vdev->priv = hw;
-
-	INIT_WORK(&hw->intr_handler, mei_virtio_intr_handler);
-
-	ret = mei_virtio_init_vqs(hw, vdev);
-	if (ret)
-		goto vqs_failed;
-
-	virtio_cread(vdev, struct mei_virtio_cfg,
-		     buf_depth, &hw->cfg.buf_depth);
-
-	hw->recv_buf = kzalloc(mei_slots2data(hw->cfg.buf_depth), GFP_KERNEL);
-	if (!hw->recv_buf) {
-		ret = -ENOMEM;
-		goto hbuf_failed;
-	}
-	atomic_set(&hw->hbuf_ready, 0);
-
-	virtio_device_ready(vdev);
-
-	mei_device_init(&hw->mdev, &vdev->dev, &mei_virtio_ops);
-
-	pm_runtime_get_noresume(&vdev->dev);
-	pm_runtime_set_active(&vdev->dev);
-	pm_runtime_enable(&vdev->dev);
-
-	ret = mei_start(&hw->mdev);
-	if (ret)
-		goto mei_start_failed;
-
-	pm_runtime_set_autosuspend_delay(&vdev->dev, MEI_VIRTIO_RPM_TIMEOUT);
-	pm_runtime_use_autosuspend(&vdev->dev);
-
-	ret = mei_register(&hw->mdev, &vdev->dev);
-	if (ret)
-		goto mei_failed;
-
-	pm_runtime_put(&vdev->dev);
-
-	return 0;
-
-mei_failed:
-	mei_stop(&hw->mdev);
-mei_start_failed:
-	mei_cancel_work(&hw->mdev);
-	mei_disable_interrupts(&hw->mdev);
-	kfree(hw->recv_buf);
-hbuf_failed:
-	vdev->config->del_vqs(vdev);
-vqs_failed:
-	return ret;
-}
-
-static int __maybe_unused mei_virtio_pm_runtime_idle(struct device *device)
-{
-	struct virtio_device *vdev = dev_to_virtio(device);
-	struct mei_virtio_hw *hw = vdev->priv;
-
-	dev_dbg(&vdev->dev, "rpm: mei_virtio : runtime_idle\n");
-
-	if (!hw)
-		return -ENODEV;
-
-	if (mei_write_is_idle(&hw->mdev))
-		pm_runtime_autosuspend(device);
-
-	return -EBUSY;
-}
-
-static int __maybe_unused mei_virtio_pm_runtime_suspend(struct device *device)
-{
-	return 0;
-}
-
-static int __maybe_unused mei_virtio_pm_runtime_resume(struct device *device)
-{
-	return 0;
-}
-
-static int __maybe_unused mei_virtio_freeze(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw = vdev->priv;
-
-	dev_dbg(&vdev->dev, "freeze\n");
-
-	if (!hw)
-		return -ENODEV;
-
-	mei_stop(&hw->mdev);
-	mei_disable_interrupts(&hw->mdev);
-	cancel_work_sync(&hw->intr_handler);
-	vdev->config->reset(vdev);
-	mei_virtio_remove_vqs(vdev);
-
-	return 0;
-}
-
-static int __maybe_unused mei_virtio_restore(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw = vdev->priv;
-	int ret;
-
-	dev_dbg(&vdev->dev, "restore\n");
-
-	if (!hw)
-		return -ENODEV;
-
-	ret = mei_virtio_init_vqs(hw, vdev);
-	if (ret)
-		return ret;
-
-	virtio_device_ready(vdev);
-
-	ret = mei_restart(&hw->mdev);
-	if (ret)
-		return ret;
-
-	/* Start timer if stopped in suspend */
-	schedule_delayed_work(&hw->mdev.timer_work, HZ);
-
-	return 0;
-}
-
-static const struct dev_pm_ops mei_virtio_pm_ops = {
-	SET_RUNTIME_PM_OPS(mei_virtio_pm_runtime_suspend,
-			   mei_virtio_pm_runtime_resume,
-			   mei_virtio_pm_runtime_idle)
-};
-
-static void mei_virtio_remove(struct virtio_device *vdev)
-{
-	struct mei_virtio_hw *hw = vdev->priv;
-
-	mei_stop(&hw->mdev);
-	mei_disable_interrupts(&hw->mdev);
-	cancel_work_sync(&hw->intr_handler);
-	mei_deregister(&hw->mdev);
-	vdev->config->reset(vdev);
-	mei_virtio_remove_vqs(vdev);
-	kfree(hw->recv_buf);
-	pm_runtime_disable(&vdev->dev);
-}
-
-static struct virtio_device_id id_table[] = {
-	{ VIRTIO_ID_MEI, VIRTIO_DEV_ANY_ID },
-	{ }
-};
-
-static struct virtio_driver mei_virtio_driver = {
-	.id_table = id_table,
-	.probe = mei_virtio_probe,
-	.remove = mei_virtio_remove,
-	.config_changed = mei_virtio_config_changed,
-	.driver = {
-		.name = KBUILD_MODNAME,
-		.owner = THIS_MODULE,
-		.pm = &mei_virtio_pm_ops,
-	},
-#ifdef CONFIG_PM_SLEEP
-	.freeze = mei_virtio_freeze,
-	.restore = mei_virtio_restore,
-#endif
-};
-
-module_virtio_driver(mei_virtio_driver);
-MODULE_DEVICE_TABLE(virtio, id_table);
-MODULE_DESCRIPTION("Virtio MEI frontend driver");
-MODULE_LICENSE("GPL v2");