[PATCH 3/3] ARM: exynos: Size combiner_data dynamically after dt parsing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The number of combiner_data entries depends on the device tree parsing
now.  Allocate the array based on the results of the parsing or fall
back on EXYNOS4 or EXYNOS5 defaults based on the SOC running.

Signed-off-by: Jonathan Kliegman <kliegs@xxxxxxxxxxxx>
---
 arch/arm/mach-exynos/common.c |   41 +++++++++++++++++++++++++----------------
 1 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 3627869..5075e0c 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -412,7 +412,7 @@ struct combiner_chip_data {
 };
 
 static struct irq_domain *combiner_irq_domain;
-static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
+static struct combiner_chip_data *combiner_data;
 static unsigned int rt_max_combiner_nr;
 
 static inline void __iomem *combiner_base(struct irq_data *data)
@@ -474,15 +474,6 @@ static struct irq_chip combiner_chip = {
 
 static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
 {
-	unsigned int max_nr;
-
-	if (soc_is_exynos5250())
-		max_nr = EXYNOS5_MAX_COMBINER_NR;
-	else
-		max_nr = EXYNOS4_MAX_COMBINER_NR;
-
-	if (combiner_nr >= max_nr)
-		BUG();
 	if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
 		BUG();
 	irq_set_chained_handler(irq, combiner_handle_cascade_irq);
@@ -598,20 +589,37 @@ static void __init combiner_init(void __iomem *combiner_base,
 				 struct device_node *np)
 {
 	int i, irq, irq_base;
-	unsigned int nr_irq;
+	unsigned int nr_irq, soc_max_nr;
+
+	soc_max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
+		EXYNOS4_MAX_COMBINER_NR;
 
 	if (np) {
 		if (of_property_read_u32(np, "samsung,combiner-nr",
 					 &rt_max_combiner_nr)) {
+			rt_max_combiner_nr = soc_max_nr;
 			pr_warning("%s: number of combiners not specified, "
-				"setting default as %d.\n",
-				__func__, EXYNOS4_MAX_COMBINER_NR);
-			rt_max_combiner_nr = EXYNOS4_MAX_COMBINER_NR;
+				   "setting default as %d.\n",
+				   __func__, rt_max_combiner_nr);
 		}
 	} else {
-		rt_max_combiner_nr = soc_is_exynos5250() ?
-			EXYNOS5_MAX_COMBINER_NR : EXYNOS4_MAX_COMBINER_NR;
+		rt_max_combiner_nr = soc_max_nr;
 	}
+	if (WARN_ON(rt_max_combiner_nr > soc_max_nr)) {
+		pr_warning("%s: more combiners specified (%d) than "
+			   "architecture (%d) supports.",
+			   __func__, rt_max_combiner_nr, soc_max_nr);
+		return;
+	}
+
+	combiner_data = kmalloc(sizeof(struct combiner_chip_data) *
+				rt_max_combiner_nr, GFP_KERNEL);
+	if (WARN_ON(!combiner_data)) {
+		pr_warning("%s: combiner_data memory allocation failed for %d "
+			   "entries", __func__, rt_max_combiner_nr);
+		return;
+	}
+
 	nr_irq = rt_max_combiner_nr * MAX_IRQ_IN_COMBINER;
 
 	irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
@@ -624,6 +632,7 @@ static void __init combiner_init(void __iomem *combiner_base,
 				&combiner_irq_domain_ops, &combiner_data);
 	if (WARN_ON(!combiner_irq_domain)) {
 		pr_warning("%s: irq domain init failed\n", __func__);
+		kfree(combiner_data);
 		return;
 	}
 
-- 
1.7.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux