drivers/interrupt_controller: Get the IOAPIC RTEs dynamically

The fixed number of 24 RTEs is a legacy thing, and long gone by now.
IOAPICs expose the maximum number of RTEs they have via the version
register, so let's use it.

This avoids to manually tweak a Kconfig option (which is now removed)
and fixes the RTE number for all x86 targets relevantly.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
diff --git a/drivers/interrupt_controller/Kconfig.loapic b/drivers/interrupt_controller/Kconfig.loapic
index 251b6b0..61dfe60 100644
--- a/drivers/interrupt_controller/Kconfig.loapic
+++ b/drivers/interrupt_controller/Kconfig.loapic
@@ -49,17 +49,6 @@
 	  This option signifies that the target has an IO-APIC device. This
 	  capability allows IO-APIC-dependent code to be included.
 
-config IOAPIC_NUM_RTES
-	int "Number of Redirection Table Entries available"
-	default 24
-	depends on IOAPIC
-	help
-	  This option indicates the maximum number of Redirection Table Entries
-	  (RTEs) (one per IRQ available to the IO-APIC) made available to the
-	  kernel, regardless of the number provided by the hardware itself. For
-	  most efficient usage of memory, it should match the number of IRQ lines
-	  needed by devices connected to the IO-APIC.
-
 config IOAPIC_MASK_RTE
 	bool "Mask out RTE entries on boot"
 	default y
diff --git a/drivers/interrupt_controller/intc_ioapic.c b/drivers/interrupt_controller/intc_ioapic.c
index 1269ba3..f324681 100644
--- a/drivers/interrupt_controller/intc_ioapic.c
+++ b/drivers/interrupt_controller/intc_ioapic.c
@@ -67,13 +67,6 @@
 DEVICE_MMIO_TOPLEVEL_STATIC(ioapic_regs, DT_DRV_INST(0));
 
 #define IOAPIC_REG DEVICE_MMIO_TOPLEVEL_GET(ioapic_regs)
-#define BITS_PER_IRQ  4
-#define IOAPIC_BITFIELD_HI_LO	0
-#define IOAPIC_BITFIELD_LVL_EDGE 1
-#define IOAPIC_BITFIELD_ENBL_DSBL 2
-#define IOAPIC_BITFIELD_DELIV_MODE 3
-#define BIT_POS_FOR_IRQ_OPTION(irq, option) ((irq) * BITS_PER_IRQ + (option))
-#define SUSPEND_BITS_REQD (ROUND_UP((CONFIG_IOAPIC_NUM_RTES * BITS_PER_IRQ), 32))
 
 /*
  * Destination field (bits[56:63]) defines a set of processors, which is
@@ -92,10 +85,27 @@
  */
 #define DEFAULT_RTE_DEST	(0xFF << 24)
 
+static uint32_t ioapic_rtes;
+
 #ifdef CONFIG_PM_DEVICE
 #include <power/power.h>
+
+#define BITS_PER_IRQ  4
+#define IOAPIC_BITFIELD_HI_LO	0
+#define IOAPIC_BITFIELD_LVL_EDGE 1
+#define IOAPIC_BITFIELD_ENBL_DSBL 2
+#define IOAPIC_BITFIELD_DELIV_MODE 3
+
+#define BIT_POS_FOR_IRQ_OPTION(irq, option) ((irq) * BITS_PER_IRQ + (option))
+
+/* Allocating up to 256 irq bits bufffer for RTEs, RTEs are dynamically found
+ * so let's just assume the maximum, it's only 128 bytes in total.
+ */
+#define SUSPEND_BITS_REQD (ROUND_UP((256 * BITS_PER_IRQ), 32))
+
 uint32_t ioapic_suspend_buf[SUSPEND_BITS_REQD / 32] = {0};
 static uint32_t ioapic_device_power_state = DEVICE_PM_ACTIVE_STATE;
+
 #endif
 
 static uint32_t __IoApicGet(int32_t offset);
@@ -126,23 +136,18 @@
 
 	DEVICE_MMIO_TOPLEVEL_MAP(ioapic_regs, K_MEM_CACHE_NONE);
 
+	/* Reading MRE: this will give the number of RTEs available */
+	ioapic_rtes = ((__IoApicGet(IOAPIC_VERS) &
+			IOAPIC_MRE_MASK) >> IOAPIC_MRE_POS) + 1;
+
 #ifdef CONFIG_IOAPIC_MASK_RTE
 	int32_t ix;	/* redirection table index */
 	uint32_t rteValue; /* value to copy into redirection table entry */
 
-	/*
-	 * The platform must set the Kconfig option IOAPIC_NUM_RTES to indicate
-	 * the number of redirection table entries supported by the IOAPIC.
-	 *
-	 * Note: The number of actual IRQs supported by the IOAPIC can be
-	 * determined at runtime by computing:
-	 *
-	 * ((__IoApicGet(IOAPIC_VERS) & IOAPIC_MRE_MASK) >> 16) + 1
-	 */
 	rteValue = IOAPIC_EDGE | IOAPIC_HIGH | IOAPIC_FIXED | IOAPIC_INT_MASK |
 		   IOAPIC_LOGICAL | 0 /* dummy vector */;
 
-	for (ix = 0; ix < CONFIG_IOAPIC_NUM_RTES; ix++) {
+	for (ix = 0; ix < ioapic_rtes; ix++) {
 		ioApicRedSetHi(ix, DEFAULT_RTE_DEST);
 		ioApicRedSetLo(ix, rteValue);
 	}
@@ -150,6 +155,11 @@
 	return 0;
 }
 
+uint32_t z_ioapic_num_rtes(void)
+{
+	return ioapic_rtes;
+}
+
 /**
  *
  * @brief Enable a specified APIC interrupt input line
@@ -244,7 +254,7 @@
 
 	ARG_UNUSED(port);
 	(void)memset(ioapic_suspend_buf, 0, (SUSPEND_BITS_REQD >> 3));
-	for (irq = 0; irq < CONFIG_IOAPIC_NUM_RTES; irq++) {
+	for (irq = 0; irq < ioapic_rtes; irq++) {
 		/*
 		 * The following check is to figure out the registered
 		 * IRQ lines, so as to limit ourselves to saving the
@@ -267,7 +277,7 @@
 
 	ARG_UNUSED(port);
 
-	for (irq = 0; irq < CONFIG_IOAPIC_NUM_RTES; irq++) {
+	for (irq = 0; irq < ioapic_rtes; irq++) {
 		if (_irq_to_interrupt_vector[irq]) {
 			/* Get the saved flags */
 			flags = restore_flags(irq);
diff --git a/drivers/interrupt_controller/intc_ioapic_priv.h b/drivers/interrupt_controller/intc_ioapic_priv.h
index ea56d9d..e675ea6 100644
--- a/drivers/interrupt_controller/intc_ioapic_priv.h
+++ b/drivers/interrupt_controller/intc_ioapic_priv.h
@@ -33,13 +33,10 @@
 /* Version register bits */
 
 #define IOAPIC_MRE_MASK 0x00ff0000 /* Max Red. entry mask */
+#define IOAPIC_MRE_POS 16
 #define IOAPIC_PRQ 0x00008000      /* this has IRQ reg */
 #define IOAPIC_VERSION 0x000000ff  /* version number */
 
-/* Redirection table entry number */
-
-#define MAX_REDTABLE_ENTRIES 24
-
 /* Redirection table entry bits: upper 32 bit */
 
 #define IOAPIC_DESTINATION 0xff000000
diff --git a/drivers/interrupt_controller/intc_loapic.c b/drivers/interrupt_controller/intc_loapic.c
index 527c7bf..7fe2e4f 100644
--- a/drivers/interrupt_controller/intc_loapic.c
+++ b/drivers/interrupt_controller/intc_loapic.c
@@ -20,6 +20,7 @@
 #include <drivers/interrupt_controller/loapic.h> /* public API declarations */
 #include <device.h>
 #include <drivers/interrupt_controller/sysapic.h>
+#include <drivers/interrupt_controller/ioapic.h>
 
 /* Local APIC Version Register Bits */
 
@@ -192,6 +193,12 @@
 	return 0;
 }
 
+
+uint32_t z_loapic_irq_base(void)
+{
+	return z_ioapic_num_rtes();
+}
+
 /**
  *
  * @brief Set the vector field in the specified RTE
@@ -344,7 +351,7 @@
 
 	for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) {
 
-		if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) {
+		if (_irq_to_interrupt_vector[z_loapic_irq_base() + loapic_irq]) {
 
 			/* Since vector numbers are already present in RAM/ROM,
 			 * We save only the mask bits here.
@@ -374,10 +381,11 @@
 
 	for (loapic_irq = 0; loapic_irq < LOAPIC_IRQ_COUNT; loapic_irq++) {
 
-		if (_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]) {
+		if (_irq_to_interrupt_vector[z_loapic_irq_base() + loapic_irq]) {
 			/* Configure vector and enable the required ones*/
 			z_loapic_int_vec_set(loapic_irq,
-				_irq_to_interrupt_vector[LOAPIC_IRQ_BASE + loapic_irq]);
+				_irq_to_interrupt_vector[z_loapic_irq_base() +
+							 loapic_irq]);
 
 			if (sys_bitfield_test_bit((mem_addr_t) loapic_suspend_buf,
 							loapic_irq)) {
diff --git a/drivers/interrupt_controller/intc_system_apic.c b/drivers/interrupt_controller/intc_system_apic.c
index 7c3d833..82fd55d 100644
--- a/drivers/interrupt_controller/intc_system_apic.c
+++ b/drivers/interrupt_controller/intc_system_apic.c
@@ -18,8 +18,8 @@
 #include <drivers/interrupt_controller/sysapic.h>
 #include <irq.h>
 
-#define IS_IOAPIC_IRQ(irq)  (irq < LOAPIC_IRQ_BASE)
-#define HARDWARE_IRQ_LIMIT ((LOAPIC_IRQ_BASE + LOAPIC_IRQ_COUNT) - 1)
+#define IS_IOAPIC_IRQ(irq)  (irq < z_loapic_irq_base())
+#define HARDWARE_IRQ_LIMIT ((z_loapic_irq_base() + LOAPIC_IRQ_COUNT) - 1)
 
 /**
  *
@@ -33,7 +33,7 @@
  *
  * The Galileo board virtualizes IRQs as follows:
  *
- * - The first CONFIG_IOAPIC_NUM_RTES IRQs are provided by the IOAPIC so the
+ * - The first z_ioapic_num_rtes() IRQs are provided by the IOAPIC so the
  *     IOAPIC is programmed for these IRQs
  * - The remaining IRQs are provided by the LOAPIC and hence the LOAPIC is
  *     programmed.
@@ -51,7 +51,7 @@
 	if (IS_IOAPIC_IRQ(irq)) {
 		z_ioapic_irq_set(irq, vector, flags);
 	} else {
-		z_loapic_int_vec_set(irq - LOAPIC_IRQ_BASE, vector);
+		z_loapic_int_vec_set(irq - z_loapic_irq_base(), vector);
 	}
 }
 
@@ -77,7 +77,7 @@
 	if (IS_IOAPIC_IRQ(irq)) {
 		z_ioapic_irq_enable(irq);
 	} else {
-		z_loapic_irq_enable(irq - LOAPIC_IRQ_BASE);
+		z_loapic_irq_enable(irq - z_loapic_irq_base());
 	}
 }
 
@@ -97,6 +97,6 @@
 	if (IS_IOAPIC_IRQ(irq)) {
 		z_ioapic_irq_disable(irq);
 	} else {
-		z_loapic_irq_disable(irq - LOAPIC_IRQ_BASE);
+		z_loapic_irq_disable(irq - z_loapic_irq_base());
 	}
 }