drivers/interrupt_controller: Expanding VT-D public API

Adding a way to pre-install the irg/vector on an irte and a way to get
an irte based on irq/vector.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c
index 4012f5d..60082f9 100644
--- a/drivers/interrupt_controller/intc_intel_vtd.c
+++ b/drivers/interrupt_controller/intc_intel_vtd.c
@@ -104,6 +104,82 @@
 	return 0;
 }
 
+static int vtd_ictl_set_irte_vector(const struct device *dev,
+				    uint8_t irte_idx,
+				    uint16_t vector)
+{
+	struct vtd_ictl_data *data = dev->data;
+
+	data->vectors[irte_idx] = vector;
+
+	return 0;
+}
+
+static int vtd_ictl_get_irte_by_vector(const struct device *dev,
+				       uint16_t vector)
+{
+	struct vtd_ictl_data *data = dev->data;
+	int irte_idx;
+
+	for (irte_idx = 0; irte_idx < IRTE_NUM; irte_idx++) {
+		if (data->vectors[irte_idx] == vector) {
+			return irte_idx;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static uint16_t vtd_ictl_get_irte_vector(const struct device *dev,
+					 uint8_t irte_idx)
+{
+	struct vtd_ictl_data *data = dev->data;
+
+	return data->vectors[irte_idx];
+}
+
+static int vtd_ictl_set_irte_irq(const struct device *dev,
+				 uint8_t irte_idx,
+				 unsigned int irq)
+{
+	struct vtd_ictl_data *data = dev->data;
+
+	data->irqs[irte_idx] = irq;
+
+	return 0;
+}
+
+static int vtd_ictl_get_irte_by_irq(const struct device *dev,
+				    unsigned int irq)
+{
+	struct vtd_ictl_data *data = dev->data;
+	int irte_idx;
+
+	for (irte_idx = 0; irte_idx < IRTE_NUM; irte_idx++) {
+		if (data->irqs[irte_idx] == irq) {
+			return irte_idx;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void vtd_ictl_set_irte_msi(const struct device *dev,
+				  uint8_t irte_idx, bool msi)
+{
+	struct vtd_ictl_data *data = dev->data;
+
+	data->msi[irte_idx] = msi;
+}
+
+static bool vtd_ictl_irte_is_msi(const struct device *dev,
+				 uint8_t irte_idx)
+{
+	struct vtd_ictl_data *data = dev->data;
+
+	return data->msi[irte_idx];
+}
+
 static int vtd_ictl_init(const struct device *dev)
 {
 	struct vtd_ictl_data *data = dev->data;
@@ -142,9 +218,19 @@
 	.allocate_entries = vtd_ictl_allocate_entries,
 	.remap_msi = vtd_ictl_remap_msi,
 	.remap = vtd_ictl_remap,
+	.set_irte_vector = vtd_ictl_set_irte_vector,
+	.get_irte_by_vector = vtd_ictl_get_irte_by_vector,
+	.get_irte_vector = vtd_ictl_get_irte_vector,
+	.set_irte_irq = vtd_ictl_set_irte_irq,
+	.get_irte_by_irq = vtd_ictl_get_irte_by_irq,
+	.set_irte_msi = vtd_ictl_set_irte_msi,
+	.irte_is_msi = vtd_ictl_irte_is_msi
 };
 
-static struct vtd_ictl_data vtd_ictl_data_0;
+static struct vtd_ictl_data vtd_ictl_data_0 = {
+	.irqs = { -EINVAL },
+	.vectors = { -EINVAL },
+};
 
 static const struct vtd_ictl_cfg vtd_ictl_cfg_0 = {
 	DEVICE_MMIO_ROM_INIT(DT_DRV_INST(0)),
diff --git a/drivers/interrupt_controller/intc_intel_vtd.h b/drivers/interrupt_controller/intc_intel_vtd.h
index 353d828..894d7da 100644
--- a/drivers/interrupt_controller/intc_intel_vtd.h
+++ b/drivers/interrupt_controller/intc_intel_vtd.h
@@ -48,6 +48,9 @@
 
 struct vtd_ictl_data {
 	struct vtd_irte irte[IRTE_NUM];
+	int irqs[IRTE_NUM];
+	int vectors[IRTE_NUM];
+	bool msi[IRTE_NUM];
 	int irte_num_used;
 };
 
diff --git a/include/drivers/interrupt_controller/intel_vtd.h b/include/drivers/interrupt_controller/intel_vtd.h
index a2d043e..d7db136 100644
--- a/include/drivers/interrupt_controller/intel_vtd.h
+++ b/include/drivers/interrupt_controller/intel_vtd.h
@@ -20,10 +20,41 @@
 			   uint16_t vector,
 			   uint32_t flags);
 
+typedef int (*vtd_set_irte_vector_f)(const struct device *dev,
+				     uint8_t irte_idx,
+				     uint16_t vector);
+
+typedef int (*vtd_get_irte_by_vector_f)(const struct device *dev,
+					uint16_t vector);
+
+typedef uint16_t (*vtd_get_irte_vector_f)(const struct device *dev,
+					  uint8_t irte_idx);
+
+typedef int (*vtd_set_irte_irq_f)(const struct device *dev,
+				  uint8_t irte_idx,
+				  unsigned int irq);
+
+typedef int (*vtd_get_irte_by_irq_f)(const struct device *dev,
+				     unsigned int irq);
+
+typedef void (*vtd_set_irte_msi_f)(const struct device *dev,
+				   uint8_t irte_idx,
+				   bool msi);
+
+typedef bool (*vtd_irte_is_msi_f)(const struct device *dev,
+				  uint8_t irte_idx);
+
 struct vtd_driver_api {
 	vtd_alloc_entries_f allocate_entries;
 	vtd_remap_msi_f remap_msi;
 	vtd_remap_f remap;
+	vtd_set_irte_vector_f set_irte_vector;
+	vtd_get_irte_by_vector_f get_irte_by_vector;
+	vtd_get_irte_vector_f get_irte_vector;
+	vtd_set_irte_irq_f set_irte_irq;
+	vtd_get_irte_by_irq_f get_irte_by_irq;
+	vtd_set_irte_msi_f set_irte_msi;
+	vtd_irte_is_msi_f irte_is_msi;
 };
 
 /**
@@ -85,5 +116,113 @@
 	return api->remap(dev, irte_idx, vector, flags);
 }
 
+/**
+ * @brief Set the vector on the allocated irte
+ *
+ * @param dev Pointer to the device structure for the driver instance
+ * @param irte_idx A previoulsy allocated irte entry index number
+ * @param vector An allocated interrupt vector
+ *
+ * @return 0, a negative errno otherwise
+ */
+static inline int vtd_set_irte_vector(const struct device *dev,
+				      uint8_t irte_idx,
+				      uint16_t vector)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->set_irte_vector(dev, irte_idx, vector);
+}
+
+/**
+ * @brief Get the irte allocated for the given vector
+ *
+ * @param dev Pointer to the device structure for the driver instance
+ * @param vector An allocated interrupt vector
+ *
+ * @return 0 or positive value on success, a negative errno otherwise
+ */
+static inline int vtd_get_irte_by_vector(const struct device *dev,
+					 uint16_t vector)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->get_irte_by_vector(dev, vector);
+}
+
+/**
+ * @brief Get the vector given to the IRTE
+ *
+ * @param dev Pointer to the device structure for the driver instance
+ * @param irte_idx A previoulsy allocated irte entry index number
+ *
+ * @return the vector set to this IRTE
+ */
+static inline uint16_t vtd_get_irte_vector(const struct device *dev,
+					   uint8_t irte_idx)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->get_irte_vector(dev, irte_idx);
+}
+
+/**
+ * @brief Set the irq on the allocated irte
+ *
+ * @param dev Pointer to the device structure for the driver instance
+ * @param irte_idx A previoulsy allocated irte entry index number
+ * @param irq A valid IRQ number
+ *
+ * @return 0, a negative errno otherwise
+ */
+static inline int vtd_set_irte_irq(const struct device *dev,
+				   uint8_t irte_idx,
+				   unsigned int irq)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->set_irte_irq(dev, irte_idx, irq);
+}
+
+/**
+ * @brief Get the irte allocated for the given irq
+ *
+ * @param dev Pointer to the device structure for the driver instance
+ * @param irq A valid IRQ number
+ *
+ * @return 0 or positive value on success, a negative errno otherwise
+ */
+static inline int vtd_get_irte_by_irq(const struct device *dev,
+				      unsigned int irq)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->get_irte_by_irq(dev, irq);
+}
+
+static inline void vtd_set_irte_msi(const struct device *dev,
+				    uint8_t irte_idx,
+				    bool msi)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->set_irte_msi(dev, irte_idx, msi);
+}
+
+static inline bool vtd_irte_is_msi(const struct device *dev,
+				   uint8_t irte_idx)
+{
+	const struct vtd_driver_api *api =
+		(const struct vtd_driver_api *)dev->api;
+
+	return api->irte_is_msi(dev, irte_idx);
+}
+
 
 #endif /* ZEPHYR_INCLUDE_DRIVERS_INTEL_VTD_H_ */