aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-17 00:20:28 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-17 00:20:28 -0400
commit36dbe4d6bffb90fcb2663ac50af00a942412e246 (patch)
tree4d24a2165620fa8fad0454299a8f5412555bba61 /arch
parente0f88db3028798b5e6d62d1c65c991240bf317f3 (diff)
parentd0a2b7af27f6d01a443f3af8252fa0b955bf1913 (diff)
Merge branch 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/kernel/avr32
* 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/kernel/avr32: [AVR32] Implement platform hooks for atmel_lcdfb driver [AVR32] Wire up signalfd, timerfd and eventfd [AVR32] optimize pagefault path [AVR32] Remove bogus comment in arch/avr32/kernel/irq.c
Diffstat (limited to 'arch')
-rw-r--r--arch/avr32/boards/atstk1000/atstk1000.h15
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c10
-rw-r--r--arch/avr32/boards/atstk1000/setup.c45
-rw-r--r--arch/avr32/kernel/irq.c9
-rw-r--r--arch/avr32/kernel/kprobes.c7
-rw-r--r--arch/avr32/kernel/syscall_table.S3
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c77
-rw-r--r--arch/avr32/mm/fault.c36
8 files changed, 140 insertions, 62 deletions
diff --git a/arch/avr32/boards/atstk1000/atstk1000.h b/arch/avr32/boards/atstk1000/atstk1000.h
new file mode 100644
index 000000000000..9a49ed036b72
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/atstk1000.h
@@ -0,0 +1,15 @@
1/*
2 * ATSTK1000 setup code: Daughterboard interface
3 *
4 * Copyright (C) 2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
11#define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
12
13extern struct atmel_lcdfb_info atstk1000_lcdc_data;
14
15#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index abe6ca203fa7..fe1dbe2e28f4 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -16,6 +16,8 @@
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/spi/spi.h> 17#include <linux/spi/spi.h>
18 18
19#include <video/atmel_lcdc.h>
20
19#include <asm/io.h> 21#include <asm/io.h>
20#include <asm/setup.h> 22#include <asm/setup.h>
21#include <asm/arch/at32ap7000.h> 23#include <asm/arch/at32ap7000.h>
@@ -23,6 +25,7 @@
23#include <asm/arch/init.h> 25#include <asm/arch/init.h>
24#include <asm/arch/portmux.h> 26#include <asm/arch/portmux.h>
25 27
28#include "atstk1000.h"
26 29
27#define SW2_DEFAULT /* MMCI and UART_A available */ 30#define SW2_DEFAULT /* MMCI and UART_A available */
28 31
@@ -31,9 +34,7 @@ struct eth_addr {
31}; 34};
32 35
33static struct eth_addr __initdata hw_addr[2]; 36static struct eth_addr __initdata hw_addr[2];
34
35static struct eth_platform_data __initdata eth_data[2]; 37static struct eth_platform_data __initdata eth_data[2];
36static struct lcdc_platform_data atstk1000_fb0_data;
37 38
38static struct spi_board_info spi0_board_info[] __initdata = { 39static struct spi_board_info spi0_board_info[] __initdata = {
39 { 40 {
@@ -148,9 +149,8 @@ static int __init atstk1002_init(void)
148 set_hw_addr(at32_add_device_eth(0, &eth_data[0])); 149 set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
149 150
150 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); 151 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
151 atstk1000_fb0_data.fbmem_start = fbmem_start; 152 at32_add_device_lcdc(0, &atstk1000_lcdc_data,
152 atstk1000_fb0_data.fbmem_size = fbmem_size; 153 fbmem_start, fbmem_size);
153 at32_add_device_lcdc(0, &atstk1000_fb0_data);
154 154
155 return 0; 155 return 0;
156} 156}
diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c
index 2bc4b88d7edb..c9af409ada9a 100644
--- a/arch/avr32/boards/atstk1000/setup.c
+++ b/arch/avr32/boards/atstk1000/setup.c
@@ -8,13 +8,56 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/fb.h>
11#include <linux/init.h> 12#include <linux/init.h>
12#include <linux/types.h> 13#include <linux/types.h>
13#include <linux/linkage.h> 14#include <linux/linkage.h>
14 15
15#include <asm/setup.h> 16#include <video/atmel_lcdc.h>
16 17
18#include <asm/setup.h>
17#include <asm/arch/board.h> 19#include <asm/arch/board.h>
18 20
21#include "atstk1000.h"
22
19/* Initialized by bootloader-specific startup code. */ 23/* Initialized by bootloader-specific startup code. */
20struct tag *bootloader_tags __initdata; 24struct tag *bootloader_tags __initdata;
25
26static struct fb_videomode __initdata ltv350qv_modes[] = {
27 {
28 .name = "320x240 @ 75",
29 .refresh = 75,
30 .xres = 320, .yres = 240,
31 .pixclock = KHZ2PICOS(6891),
32
33 .left_margin = 17, .right_margin = 33,
34 .upper_margin = 10, .lower_margin = 10,
35 .hsync_len = 16, .vsync_len = 1,
36
37 .sync = 0,
38 .vmode = FB_VMODE_NONINTERLACED,
39 },
40};
41
42static struct fb_monspecs __initdata atstk1000_default_monspecs = {
43 .manufacturer = "SNG",
44 .monitor = "LTV350QV",
45 .modedb = ltv350qv_modes,
46 .modedb_len = ARRAY_SIZE(ltv350qv_modes),
47 .hfmin = 14820,
48 .hfmax = 22230,
49 .vfmin = 60,
50 .vfmax = 90,
51 .dclkmax = 30000000,
52};
53
54struct atmel_lcdfb_info __initdata atstk1000_lcdc_data = {
55 .default_bpp = 24,
56 .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
57 .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
58 | ATMEL_LCDC_INVCLK
59 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
60 | ATMEL_LCDC_MEMOR_BIG),
61 .default_monspecs = &atstk1000_default_monspecs,
62 .guard_time = 2,
63};
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
index fd311248c143..61f2de266f62 100644
--- a/arch/avr32/kernel/irq.c
+++ b/arch/avr32/kernel/irq.c
@@ -7,15 +7,6 @@
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 *
11 * This file contains the code used by various IRQ handling routines:
12 * asking for different IRQ's should be done through these routines
13 * instead of just grabbing them. Thus setups with different IRQ numbers
14 * shouldn't result in any weird surprises, and installing new handlers
15 * should be easier.
16 *
17 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
18 * Naturally it's not a 1:1 relation, but there are similarities.
19 */ 10 */
20 11
21#include <linux/interrupt.h> 12#include <linux/interrupt.h>
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 004c94b6fc1d..4942ee662e0b 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -179,7 +179,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
179 return 1; 179 return 1;
180} 180}
181 181
182static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 182int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
183{ 183{
184 struct kprobe *cur = kprobe_running(); 184 struct kprobe *cur = kprobe_running();
185 185
@@ -216,11 +216,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
216 if (post_kprobe_handler(args->regs)) 216 if (post_kprobe_handler(args->regs))
217 ret = NOTIFY_STOP; 217 ret = NOTIFY_STOP;
218 break; 218 break;
219 case DIE_FAULT:
220 if (kprobe_running()
221 && kprobe_fault_handler(args->regs, args->trapnr))
222 ret = NOTIFY_STOP;
223 break;
224 default: 219 default:
225 break; 220 break;
226 } 221 }
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
index 07f6a6fa340d..75c81f2dd0b3 100644
--- a/arch/avr32/kernel/syscall_table.S
+++ b/arch/avr32/kernel/syscall_table.S
@@ -292,4 +292,7 @@ sys_call_table:
292 .long sys_shmdt 292 .long sys_shmdt
293 .long sys_shmctl 293 .long sys_shmctl
294 .long sys_utimensat 294 .long sys_utimensat
295 .long sys_signalfd
296 .long sys_timerfd /* 280 */
297 .long sys_eventfd
295 .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ 298 .long sys_ni_syscall /* r8 is saturated at nr_syscalls */
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index 56db45b99a0f..1d2bf347a1d6 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -6,6 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8#include <linux/clk.h> 8#include <linux/clk.h>
9#include <linux/fb.h>
9#include <linux/init.h> 10#include <linux/init.h>
10#include <linux/platform_device.h> 11#include <linux/platform_device.h>
11#include <linux/spi/spi.h> 12#include <linux/spi/spi.h>
@@ -17,6 +18,8 @@
17#include <asm/arch/portmux.h> 18#include <asm/arch/portmux.h>
18#include <asm/arch/sm.h> 19#include <asm/arch/sm.h>
19 20
21#include <video/atmel_lcdc.h>
22
20#include "clock.h" 23#include "clock.h"
21#include "hmatrix.h" 24#include "hmatrix.h"
22#include "pio.h" 25#include "pio.h"
@@ -881,20 +884,26 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
881/* -------------------------------------------------------------------- 884/* --------------------------------------------------------------------
882 * LCDC 885 * LCDC
883 * -------------------------------------------------------------------- */ 886 * -------------------------------------------------------------------- */
884static struct lcdc_platform_data lcdc0_data; 887static struct atmel_lcdfb_info atmel_lcdfb0_data;
885static struct resource lcdc0_resource[] = { 888static struct resource atmel_lcdfb0_resource[] = {
886 { 889 {
887 .start = 0xff000000, 890 .start = 0xff000000,
888 .end = 0xff000fff, 891 .end = 0xff000fff,
889 .flags = IORESOURCE_MEM, 892 .flags = IORESOURCE_MEM,
890 }, 893 },
891 IRQ(1), 894 IRQ(1),
895 {
896 /* Placeholder for pre-allocated fb memory */
897 .start = 0x00000000,
898 .end = 0x00000000,
899 .flags = 0,
900 },
892}; 901};
893DEFINE_DEV_DATA(lcdc, 0); 902DEFINE_DEV_DATA(atmel_lcdfb, 0);
894DEV_CLK(hclk, lcdc0, hsb, 7); 903DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);
895static struct clk lcdc0_pixclk = { 904static struct clk atmel_lcdfb0_pixclk = {
896 .name = "pixclk", 905 .name = "lcdc_clk",
897 .dev = &lcdc0_device.dev, 906 .dev = &atmel_lcdfb0_device.dev,
898 .mode = genclk_mode, 907 .mode = genclk_mode,
899 .get_rate = genclk_get_rate, 908 .get_rate = genclk_get_rate,
900 .set_rate = genclk_set_rate, 909 .set_rate = genclk_set_rate,
@@ -903,13 +912,34 @@ static struct clk lcdc0_pixclk = {
903}; 912};
904 913
905struct platform_device *__init 914struct platform_device *__init
906at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) 915at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
916 unsigned long fbmem_start, unsigned long fbmem_len)
907{ 917{
908 struct platform_device *pdev; 918 struct platform_device *pdev;
919 struct atmel_lcdfb_info *info;
920 struct fb_monspecs *monspecs;
921 struct fb_videomode *modedb;
922 unsigned int modedb_size;
923
924 /*
925 * Do a deep copy of the fb data, monspecs and modedb. Make
926 * sure all allocations are done before setting up the
927 * portmux.
928 */
929 monspecs = kmemdup(data->default_monspecs,
930 sizeof(struct fb_monspecs), GFP_KERNEL);
931 if (!monspecs)
932 return NULL;
933
934 modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;
935 modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);
936 if (!modedb)
937 goto err_dup_modedb;
938 monspecs->modedb = modedb;
909 939
910 switch (id) { 940 switch (id) {
911 case 0: 941 case 0:
912 pdev = &lcdc0_device; 942 pdev = &atmel_lcdfb0_device;
913 select_peripheral(PC(19), PERIPH_A, 0); /* CC */ 943 select_peripheral(PC(19), PERIPH_A, 0); /* CC */
914 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ 944 select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
915 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ 945 select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
@@ -942,19 +972,32 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
942 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ 972 select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
943 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ 973 select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
944 974
945 clk_set_parent(&lcdc0_pixclk, &pll0); 975 clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
946 clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); 976 clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
947 break; 977 break;
948 978
949 default: 979 default:
950 return NULL; 980 goto err_invalid_id;
951 } 981 }
952 982
953 memcpy(pdev->dev.platform_data, data, 983 if (fbmem_len) {
954 sizeof(struct lcdc_platform_data)); 984 pdev->resource[2].start = fbmem_start;
985 pdev->resource[2].end = fbmem_start + fbmem_len - 1;
986 pdev->resource[2].flags = IORESOURCE_MEM;
987 }
988
989 info = pdev->dev.platform_data;
990 memcpy(info, data, sizeof(struct atmel_lcdfb_info));
991 info->default_monspecs = monspecs;
955 992
956 platform_device_register(pdev); 993 platform_device_register(pdev);
957 return pdev; 994 return pdev;
995
996err_invalid_id:
997 kfree(modedb);
998err_dup_modedb:
999 kfree(monspecs);
1000 return NULL;
958} 1001}
959 1002
960/* -------------------------------------------------------------------- 1003/* --------------------------------------------------------------------
@@ -1037,8 +1080,8 @@ struct clk *at32_clock_list[] = {
1037 &macb1_pclk, 1080 &macb1_pclk,
1038 &atmel_spi0_spi_clk, 1081 &atmel_spi0_spi_clk,
1039 &atmel_spi1_spi_clk, 1082 &atmel_spi1_spi_clk,
1040 &lcdc0_hclk, 1083 &atmel_lcdfb0_hck1,
1041 &lcdc0_pixclk, 1084 &atmel_lcdfb0_pixclk,
1042 &gclk0, 1085 &gclk0,
1043 &gclk1, 1086 &gclk1,
1044 &gclk2, 1087 &gclk2,
@@ -1077,7 +1120,7 @@ void __init at32_clock_init(void)
1077 genclk_init_parent(&gclk2); 1120 genclk_init_parent(&gclk2);
1078 genclk_init_parent(&gclk3); 1121 genclk_init_parent(&gclk3);
1079 genclk_init_parent(&gclk4); 1122 genclk_init_parent(&gclk4);
1080 genclk_init_parent(&lcdc0_pixclk); 1123 genclk_init_parent(&atmel_lcdfb0_pixclk);
1081 1124
1082 /* 1125 /*
1083 * Turn on all clocks that have at least one user already, and 1126 * Turn on all clocks that have at least one user already, and
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 88b00b15970f..e011f1ce1875 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -12,41 +12,30 @@
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pagemap.h> 14#include <linux/pagemap.h>
15
16#include <linux/kdebug.h> 15#include <linux/kdebug.h>
16#include <linux/kprobes.h>
17
17#include <asm/mmu_context.h> 18#include <asm/mmu_context.h>
18#include <asm/sysreg.h> 19#include <asm/sysreg.h>
19#include <asm/tlb.h> 20#include <asm/tlb.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21 22
22#ifdef CONFIG_KPROBES 23#ifdef CONFIG_KPROBES
23ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 24static inline int notify_page_fault(struct pt_regs *regs, int trap)
24
25/* Hook to register for page fault notifications */
26int register_page_fault_notifier(struct notifier_block *nb)
27{ 25{
28 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 26 int ret = 0;
29}
30 27
31int unregister_page_fault_notifier(struct notifier_block *nb) 28 if (!user_mode(regs)) {
32{ 29 if (kprobe_running() && kprobe_fault_handler(regs, trap))
33 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 30 ret = 1;
34} 31 }
35 32
36static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, 33 return ret;
37 int trap, int sig)
38{
39 struct die_args args = {
40 .regs = regs,
41 .trapnr = trap,
42 };
43 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
44} 34}
45#else 35#else
46static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, 36static inline int notify_page_fault(struct pt_regs *regs, int trap)
47 int trap, int sig)
48{ 37{
49 return NOTIFY_DONE; 38 return 0;
50} 39}
51#endif 40#endif
52 41
@@ -76,8 +65,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
76 long signr; 65 long signr;
77 int code; 66 int code;
78 67
79 if (notify_page_fault(DIE_PAGE_FAULT, regs, 68 if (notify_page_fault(regs, ecr))
80 ecr, SIGSEGV) == NOTIFY_STOP)
81 return; 69 return;
82 70
83 address = sysreg_read(TLBEAR); 71 address = sysreg_read(TLBEAR);