Re: Sun4d boot crash in sun4d_init_timers

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

 



On Mon, May 23, 2011 at 02:59:49PM -0400, daniel@xxxxxxxxxxx wrote:
> First of all you're right calling will NULL just can't be good. The
> LEON genirq build_device_irq has been split into two separate parts,
> one that takes a platofrm device and one that works with "real_irq"
> just because of this reason. Even though the OpenBoot PROM shuold
> deliver all information, I think we should be able to bypass it when
> needed, like in this case.
> 
> Secondly, the return value from sun4d_build_device_irq() is a
> real_irq, and that is what causes the problem I guess. Try make it
> return the virtual IRQ instead, and give that VIRQ to request_irq
> instead.

Yeah, something like this (completely untested):

diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index a9ea60e..c18c5f2 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -305,7 +305,6 @@ unsigned int sun4d_build_device_irq(struct platform_device *op,
 	struct device_node *dp = op->dev.of_node;
 	struct device_node *io_unit, *sbi = dp->parent;
 	const struct linux_prom_registers *regs;
-	struct sun4d_handler_data *handler_data;
 	unsigned int pil;
 	unsigned int irq;
 	int board, slot;
@@ -348,6 +347,19 @@ unsigned int sun4d_build_device_irq(struct platform_device *op,
 	else
 		pil = real_irq;
 
+	return _sun4d_build_device_irq(real_irq, pil, board);
+
+err_out:
+	return irq;
+}
+
+unsigned int _sun4d_build_device_irq(unsigned int real_irq,
+                                     unsigned int pil,
+                                     unsigned int board)
+{
+	struct sun4d_handler_data *handler_data;
+	unsigned int irq;
+
 	irq = irq_alloc(real_irq, pil);
 	if (irq == 0)
 		goto err_out;
@@ -368,7 +380,12 @@ unsigned int sun4d_build_device_irq(struct platform_device *op,
 	irq_set_handler_data(irq, handler_data);
 
 err_out:
-	return real_irq;
+	return irq;
+}
+
+unsigned int sun4d_build_timer_irq(unsigned int board, unsigned int real_irq)
+{
+        return _sun4d_build_device_irq(real_irq, real_irq, board);
 }
 
 static void __init sun4d_fixup_trap_table(void)
@@ -402,6 +419,7 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
 	unsigned int irq;
 	const u32 *reg;
 	int err;
+	int board;
 
 	dp = of_find_node_by_name(NULL, "cpu-unit");
 	if (!dp) {
@@ -414,12 +432,19 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
 	 * bootbus.
 	 */
 	reg = of_get_property(dp, "reg", NULL);
-	of_node_put(dp);
 	if (!reg) {
 		prom_printf("sun4d_init_timers: No reg property\n");
 		prom_halt();
 	}
 
+	board = of_getintprop_default(dp, "board#", 0);
+	if (!board) {
+		prom_printf("sun4d_init_timers: No board# property on cpu-unit\n");
+		prom_halt();
+	}
+
+	of_node_put(dp);
+
 	res.start = reg[1];
 	res.end = reg[2] - 1;
 	res.flags = reg[0] & 0xff;
@@ -434,7 +459,7 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
 
 	master_l10_counter = &sun4d_timers->l10_cur_count;
 
-	irq = sun4d_build_device_irq(NULL, SUN4D_TIMER_IRQ);
+	irq = sun4d_build_timer_irq(board, SUN4D_TIMER_IRQ);
 	err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
 	if (err) {
 		prom_printf("sun4d_init_timers: request_irq() failed with %d\n",


Passing around the 'board' property of 'cpu-unit' looks like it should be done
because the same thing is used to seed board_to_cpu[].

http://git.kernel.org/?p=linux/kernel/git/davem/prtconfs.git;a=blob;f=ss1000;h=f420dc005d6939b837134d146741316c024d5932;hb=HEAD
says both cpu-units have the same, zeroth board, but it might not hurt
to check just in case some other machine happens to use a different index.

-- 
     2. That which causes joy or happiness.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Development]     [DCCP]     [Linux ARM Development]     [Linux]     [Photo]     [Yosemite Help]     [Linux ARM Kernel]     [Linux SCSI]     [Linux x86_64]     [Linux Hams]

  Powered by Linux