From 8faf9e3838c31c426e6203cb7dc6fc0f0bdb8b7e Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Sun, 10 Apr 2011 14:14:43 +0800 Subject: [PATCH 1/7] fix the wrong argument of the functions definition The functions of eic_chip's memebers use the wrong argument . Signed-off-by: Wanlong Gao Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/mach-at32ap/extint.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 47ba4b9b6db1..755ac599b308 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c @@ -61,34 +61,34 @@ struct eic { static struct eic *nmi_eic; static bool nmi_enabled; -static void eic_ack_irq(struct irq_chip *d) +static void eic_ack_irq(struct irq_data *d) { - struct eic *eic = irq_data_get_irq_chip_data(data); + struct eic *eic = irq_data_get_irq_chip_data(d); eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); } -static void eic_mask_irq(struct irq_chip *d) +static void eic_mask_irq(struct irq_data *d) { - struct eic *eic = irq_data_get_irq_chip_data(data); + struct eic *eic = irq_data_get_irq_chip_data(d); eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); } -static void eic_mask_ack_irq(struct irq_chip *d) +static void eic_mask_ack_irq(struct irq_data *d) { - struct eic *eic = irq_data_get_irq_chip_data(data); + struct eic *eic = irq_data_get_irq_chip_data(d); eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); } -static void eic_unmask_irq(struct irq_chip *d) +static void eic_unmask_irq(struct irq_data *d) { - struct eic *eic = irq_data_get_irq_chip_data(data); + struct eic *eic = irq_data_get_irq_chip_data(d); eic_writel(eic, IER, 1 << (d->irq - eic->first_irq)); } -static int eic_set_irq_type(struct irq_chip *d, unsigned int flow_type) +static int eic_set_irq_type(struct irq_data *d, unsigned int flow_type) { - struct eic *eic = irq_data_get_irq_chip_data(data); + struct eic *eic = irq_data_get_irq_chip_data(d); unsigned int irq = d->irq; unsigned int i = irq - eic->first_irq; u32 mode, edge, level; From 024b3f2936c9a9393d2cf37b7c537b29fb894b62 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 10 Apr 2011 06:17:20 +0200 Subject: [PATCH 2/7] avr32: At32ap: pio fix typo "))" on gpio_irq_unmask prototype introduce in commit d75f1bfdbccb Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Thomas Gleixner Cc: Hans-Christian Egtvedt Cc: Nicolas Ferre Cc: Patrice Vilchez Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/mach-at32ap/pio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index f308e1ddc629..2e0aa853a4bc 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -257,7 +257,7 @@ static void gpio_irq_mask(struct irq_data *d) pio_writel(pio, IDR, 1 << (gpio & 0x1f)); } -static void gpio_irq_unmask(struct irq_data *d)) +static void gpio_irq_unmask(struct irq_data *d) { unsigned gpio = irq_to_gpio(d->irq); struct pio_device *pio = &pio_dev[gpio >> 5]; From 51ef85d8f9ae24475a0cb1bd772258eafec91c69 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 9 Mar 2011 00:32:36 +0000 Subject: [PATCH 3/7] avr32: Fix .size directive for cpu_enter_idle gas used to accept (and ignore?) .size directives which referred to undefined symbols, as this does. In binutils 2.21 these are treated as errors. Signed-off-by: Ben Hutchings Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/mach-at32ap/pm-at32ap700x.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/mach-at32ap/pm-at32ap700x.S b/arch/avr32/mach-at32ap/pm-at32ap700x.S index 17503b0ed6c9..f868f4ce761b 100644 --- a/arch/avr32/mach-at32ap/pm-at32ap700x.S +++ b/arch/avr32/mach-at32ap/pm-at32ap700x.S @@ -53,7 +53,7 @@ cpu_enter_idle: st.w r8[TI_flags], r9 unmask_interrupts sleep CPU_SLEEP_IDLE - .size cpu_idle_sleep, . - cpu_idle_sleep + .size cpu_enter_idle, . - cpu_enter_idle /* * Common return path for PM functions that don't run from From 6e2ad51190cdb11b364377882134513f60dec6b9 Mon Sep 17 00:00:00 2001 From: Ole Henrik Jahren Date: Sun, 6 Mar 2011 20:42:39 +0100 Subject: [PATCH 4/7] avr32: fix deadlock when reading clock list in debugfs When writing out /sys/kernel/debug/at32ap_clk, clock list lock is being held while clk_get() is called. clk_get() attempts to take the same lock, which results in deadlock. Introduce and call lock free version, __clk_get(), instead. Signed-off-by: Ole Henrik Jahren Cc: Hans-Christian Egtvedt Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/mach-at32ap/clock.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c index 442f08c5e641..86925fd6ea5b 100644 --- a/arch/avr32/mach-at32ap/clock.c +++ b/arch/avr32/mach-at32ap/clock.c @@ -35,22 +35,30 @@ void at32_clk_register(struct clk *clk) spin_unlock(&clk_list_lock); } +static struct clk *__clk_get(struct device *dev, const char *id) +{ + struct clk *clk; + + list_for_each_entry(clk, &at32_clock_list, list) { + if (clk->dev == dev && strcmp(id, clk->name) == 0) { + return clk; + } + } + + return ERR_PTR(-ENOENT); +} + struct clk *clk_get(struct device *dev, const char *id) { struct clk *clk; spin_lock(&clk_list_lock); - - list_for_each_entry(clk, &at32_clock_list, list) { - if (clk->dev == dev && strcmp(id, clk->name) == 0) { - spin_unlock(&clk_list_lock); - return clk; - } - } - + clk = __clk_get(dev, id); spin_unlock(&clk_list_lock); - return ERR_PTR(-ENOENT); + + return clk; } + EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) @@ -257,15 +265,15 @@ static int clk_show(struct seq_file *s, void *unused) spin_lock(&clk_list_lock); /* show clock tree as derived from the three oscillators */ - clk = clk_get(NULL, "osc32k"); + clk = __clk_get(NULL, "osc32k"); dump_clock(clk, &r); clk_put(clk); - clk = clk_get(NULL, "osc0"); + clk = __clk_get(NULL, "osc0"); dump_clock(clk, &r); clk_put(clk); - clk = clk_get(NULL, "osc1"); + clk = __clk_get(NULL, "osc1"); dump_clock(clk, &r); clk_put(clk); From 9f0d15aac9987adaff18b85585fb7eaba266e112 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 4 Apr 2011 15:58:04 +0100 Subject: [PATCH 5/7] avr32: init cannot ignore signals sent by force_sig_info() We can delete the code that checks to see if we're sending an ignored signal to init because force_sig_info() already handles this case. force_sig_info() will kill init even if the signal handler is SIG_DFL and the scenario described in the comment where init might "generate the same exception over and over again" cannot occur (force_sig_info() clears SIGNAL_UNKILLABLE to ensure that init will die). Also, the use of is_global_init() is not correct in the multhreaded case, as Oleg Nesterov explains, "is_global_init() is not right in theory, /sbin/init can be multithreaded. And, this doesn't cover the sub-namespace inits... I'd suggest to check SIGNAL_UNKILLABLE, but looking closer I think you can simply remove this code." It seems this code was copied from arch/powerpc in March 2007 in commit 623b0355d5b1 "[AVR32] Clean up exception handling code" but the code was deleted from arch/powerpc in November 2009 in commit a0592d42fe3e "powerpc: kill the obsolete code under is_global_init()" So catch up with powerpc and delete the bogus code. Signed-off-by: Matt Fleming Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/kernel/traps.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index b91b2044af9c..7aa25756412f 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c @@ -95,28 +95,6 @@ void _exception(long signr, struct pt_regs *regs, int code, info.si_code = code; info.si_addr = (void __user *)addr; force_sig_info(signr, &info, current); - - /* - * Init gets no signals that it doesn't have a handler for. - * That's all very well, but if it has caused a synchronous - * exception and we ignore the resulting signal, it will just - * generate the same exception over and over again and we get - * nowhere. Better to kill it and let the kernel panic. - */ - if (is_global_init(current)) { - __sighandler_t handler; - - spin_lock_irq(¤t->sighand->siglock); - handler = current->sighand->action[signr-1].sa.sa_handler; - spin_unlock_irq(¤t->sighand->siglock); - if (handler == SIG_DFL) { - /* init has generated a synchronous exception - and it doesn't have a handler for the signal */ - printk(KERN_CRIT "init has generated signal %ld " - "but has no handler for it\n", signr); - do_exit(signr); - } - } } asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) From c7d876321f4cf252bc70c1995bbc077a65b3af2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 9 Feb 2011 11:28:04 +0100 Subject: [PATCH 6/7] don't check platform_get_irq's return value against zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platform_get_irq returns -ENXIO on failure, so !int_irq was probably always true. Better use (int)int_irq <= 0. Note that a return value of zero is still handled as error even though this could mean irq0. This is a followup to 305b3228f9ff4d59f49e6d34a7034d44ee8ce2f0 that changed the return value of platform_get_irq from 0 to -ENXIO on error. Acked-by: Hans-Christian Egtvedt Signed-off-by: Uwe Kleine-König Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/mach-at32ap/extint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 755ac599b308..fbc2aeaebddb 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c @@ -191,7 +191,7 @@ static int __init eic_probe(struct platform_device *pdev) regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); int_irq = platform_get_irq(pdev, 0); - if (!regs || !int_irq) { + if (!regs || (int)int_irq <= 0) { dev_dbg(&pdev->dev, "missing regs and/or irq resource\n"); return -ENXIO; } From 24a1a47562b0fbb97321191dcc3a67b337b20f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Wed, 13 Apr 2011 10:07:35 +0200 Subject: [PATCH 7/7] avr32: add ATAG_BOARDINFO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ATAG_BOARDINFO is intended to hand over the information bd->bi_board_number from u-boot to the kernel. This piece of information can be used to implement some kind of board identification while booting the kernel. Therefore it is placed in .initdata section and can be accessed via the new symbol board_number only while initializing the kernel. Signed-off-by: Andreas Bießmann Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/include/asm/setup.h | 9 +++++++++ arch/avr32/kernel/setup.c | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/arch/avr32/include/asm/setup.h b/arch/avr32/include/asm/setup.h index ff5b7cf6be4d..160543dbec7e 100644 --- a/arch/avr32/include/asm/setup.h +++ b/arch/avr32/include/asm/setup.h @@ -94,6 +94,13 @@ struct tag_ethernet { #define ETH_INVALID_PHY 0xff +/* board information */ +#define ATAG_BOARDINFO 0x54410008 + +struct tag_boardinfo { + u32 board_number; +}; + struct tag { struct tag_header hdr; union { @@ -102,6 +109,7 @@ struct tag { struct tag_cmdline cmdline; struct tag_clock clock; struct tag_ethernet ethernet; + struct tag_boardinfo boardinfo; } u; }; @@ -128,6 +136,7 @@ extern struct tag *bootloader_tags; extern resource_size_t fbmem_start; extern resource_size_t fbmem_size; +extern u32 board_number; void setup_processor(void); diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index 5c7083916c33..bb0974cce4ac 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -390,6 +390,21 @@ static int __init parse_tag_clock(struct tag *tag) } __tagtable(ATAG_CLOCK, parse_tag_clock); +/* + * The board_number correspond to the bd->bi_board_number in U-Boot. This + * parameter is only available during initialisation and can be used in some + * kind of board identification. + */ +u32 __initdata board_number; + +static int __init parse_tag_boardinfo(struct tag *tag) +{ + board_number = tag->u.boardinfo.board_number; + + return 0; +} +__tagtable(ATAG_BOARDINFO, parse_tag_boardinfo); + /* * Scan the tag table for this tag, and call its parse function. The * tag table is built by the linker from all the __tagtable