diff options
Diffstat (limited to 'arch/avr32')
-rw-r--r-- | arch/avr32/boards/atstk1000/Makefile | 2 | ||||
-rw-r--r-- | arch/avr32/boards/atstk1000/atstk1002.c | 52 | ||||
-rw-r--r-- | arch/avr32/boards/atstk1000/spi.c | 27 | ||||
-rw-r--r-- | arch/avr32/kernel/cpu.c | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/setup.c | 10 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall_table.S | 22 | ||||
-rw-r--r-- | arch/avr32/kernel/time.c | 11 | ||||
-rw-r--r-- | arch/avr32/kernel/vmlinux.lds.c | 2 | ||||
-rw-r--r-- | arch/avr32/lib/libgcc.h | 33 | ||||
-rw-r--r-- | arch/avr32/lib/longlong.h | 98 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/Makefile | 2 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 172 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/clock.c | 6 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/extint.c | 36 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/pio.c | 255 | ||||
-rw-r--r-- | arch/avr32/mm/cache.c | 32 | ||||
-rw-r--r-- | arch/avr32/mm/tlb.c | 2 |
18 files changed, 503 insertions, 261 deletions
diff --git a/arch/avr32/boards/atstk1000/Makefile b/arch/avr32/boards/atstk1000/Makefile index df9499480530..8e0992201bb9 100644 --- a/arch/avr32/boards/atstk1000/Makefile +++ b/arch/avr32/boards/atstk1000/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-y += setup.o spi.o flash.o | 1 | obj-y += setup.o flash.o |
2 | obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o | 2 | obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o |
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 32b361f31c2c..5974768a59e5 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
@@ -14,11 +14,17 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/spi/spi.h> | ||
17 | 18 | ||
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
19 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
21 | #include <asm/arch/at32ap7000.h> | ||
20 | #include <asm/arch/board.h> | 22 | #include <asm/arch/board.h> |
21 | #include <asm/arch/init.h> | 23 | #include <asm/arch/init.h> |
24 | #include <asm/arch/portmux.h> | ||
25 | |||
26 | |||
27 | #define SW2_DEFAULT /* MMCI and UART_A available */ | ||
22 | 28 | ||
23 | struct eth_addr { | 29 | struct eth_addr { |
24 | u8 addr[6]; | 30 | u8 addr[6]; |
@@ -29,6 +35,15 @@ static struct eth_addr __initdata hw_addr[2]; | |||
29 | static struct eth_platform_data __initdata eth_data[2]; | 35 | static struct eth_platform_data __initdata eth_data[2]; |
30 | extern struct lcdc_platform_data atstk1000_fb0_data; | 36 | extern struct lcdc_platform_data atstk1000_fb0_data; |
31 | 37 | ||
38 | static struct spi_board_info spi0_board_info[] __initdata = { | ||
39 | { | ||
40 | /* QVGA display */ | ||
41 | .modalias = "ltv350qv", | ||
42 | .max_speed_hz = 16000000, | ||
43 | .chip_select = 1, | ||
44 | }, | ||
45 | }; | ||
46 | |||
32 | /* | 47 | /* |
33 | * The next two functions should go away as the boot loader is | 48 | * The next two functions should go away as the boot loader is |
34 | * supposed to initialize the macb address registers with a valid | 49 | * supposed to initialize the macb address registers with a valid |
@@ -86,24 +101,53 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
86 | 101 | ||
87 | void __init setup_board(void) | 102 | void __init setup_board(void) |
88 | { | 103 | { |
89 | at32_map_usart(1, 0); /* /dev/ttyS0 */ | 104 | #ifdef SW2_DEFAULT |
90 | at32_map_usart(2, 1); /* /dev/ttyS1 */ | 105 | at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ |
91 | at32_map_usart(3, 2); /* /dev/ttyS2 */ | 106 | #else |
107 | at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ | ||
108 | #endif | ||
109 | /* USART 2/unused: expansion connector */ | ||
110 | at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */ | ||
92 | 111 | ||
93 | at32_setup_serial_console(0); | 112 | at32_setup_serial_console(0); |
94 | } | 113 | } |
95 | 114 | ||
96 | static int __init atstk1002_init(void) | 115 | static int __init atstk1002_init(void) |
97 | { | 116 | { |
117 | /* | ||
118 | * ATSTK1000 uses 32-bit SDRAM interface. Reserve the | ||
119 | * SDRAM-specific pins so that nobody messes with them. | ||
120 | */ | ||
121 | at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ | ||
122 | at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ | ||
123 | at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ | ||
124 | at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ | ||
125 | at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ | ||
126 | at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ | ||
127 | at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ | ||
128 | at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ | ||
129 | at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ | ||
130 | at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ | ||
131 | at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ | ||
132 | at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ | ||
133 | at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ | ||
134 | at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ | ||
135 | at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ | ||
136 | at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ | ||
137 | at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ | ||
138 | |||
98 | at32_add_system_devices(); | 139 | at32_add_system_devices(); |
99 | 140 | ||
141 | #ifdef SW2_DEFAULT | ||
100 | at32_add_device_usart(0); | 142 | at32_add_device_usart(0); |
143 | #else | ||
101 | at32_add_device_usart(1); | 144 | at32_add_device_usart(1); |
145 | #endif | ||
102 | at32_add_device_usart(2); | 146 | at32_add_device_usart(2); |
103 | 147 | ||
104 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); | 148 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); |
105 | 149 | ||
106 | at32_add_device_spi(0); | 150 | at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); |
107 | at32_add_device_lcdc(0, &atstk1000_fb0_data); | 151 | at32_add_device_lcdc(0, &atstk1000_fb0_data); |
108 | 152 | ||
109 | return 0; | 153 | return 0; |
diff --git a/arch/avr32/boards/atstk1000/spi.c b/arch/avr32/boards/atstk1000/spi.c deleted file mode 100644 index 567726c82c6e..000000000000 --- a/arch/avr32/boards/atstk1000/spi.c +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * ATSTK1000 SPI devices | ||
3 | * | ||
4 | * Copyright (C) 2005 Atmel Norway | ||
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 | #include <linux/device.h> | ||
11 | #include <linux/spi/spi.h> | ||
12 | |||
13 | static struct spi_board_info spi_board_info[] __initdata = { | ||
14 | { | ||
15 | .modalias = "ltv350qv", | ||
16 | .max_speed_hz = 16000000, | ||
17 | .bus_num = 0, | ||
18 | .chip_select = 1, | ||
19 | }, | ||
20 | }; | ||
21 | |||
22 | static int board_init_spi(void) | ||
23 | { | ||
24 | spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); | ||
25 | return 0; | ||
26 | } | ||
27 | arch_initcall(board_init_spi); | ||
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index 342452ba2049..2e72fd2699df 100644 --- a/arch/avr32/kernel/cpu.c +++ b/arch/avr32/kernel/cpu.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/sysdev.h> | 9 | #include <linux/sysdev.h> |
10 | #include <linux/seq_file.h> | 10 | #include <linux/seq_file.h> |
11 | #include <linux/cpu.h> | 11 | #include <linux/cpu.h> |
12 | #include <linux/module.h> | ||
12 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
13 | #include <linux/param.h> | 14 | #include <linux/param.h> |
14 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c index 856f3548e664..fd311248c143 100644 --- a/arch/avr32/kernel/irq.c +++ b/arch/avr32/kernel/irq.c | |||
@@ -57,6 +57,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
57 | seq_printf(p, "%3d: ", i); | 57 | seq_printf(p, "%3d: ", i); |
58 | for_each_online_cpu(cpu) | 58 | for_each_online_cpu(cpu) |
59 | seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); | 59 | seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); |
60 | seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); | ||
60 | seq_printf(p, " %s", action->name); | 61 | seq_printf(p, " %s", action->name); |
61 | for (action = action->next; action; action = action->next) | 62 | for (action = action->next; action; action = action->next) |
62 | seq_printf(p, ", %s", action->name); | 63 | seq_printf(p, ", %s", action->name); |
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index a34211601008..a1a7c3c3f522 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/root_dev.h> | 17 | #include <linux/root_dev.h> |
18 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
19 | #include <linux/kernel.h> | ||
19 | 20 | ||
20 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
21 | #include <asm/processor.h> | 22 | #include <asm/processor.h> |
@@ -44,7 +45,7 @@ struct avr32_cpuinfo boot_cpu_data = { | |||
44 | }; | 45 | }; |
45 | EXPORT_SYMBOL(boot_cpu_data); | 46 | EXPORT_SYMBOL(boot_cpu_data); |
46 | 47 | ||
47 | static char command_line[COMMAND_LINE_SIZE]; | 48 | static char __initdata command_line[COMMAND_LINE_SIZE]; |
48 | 49 | ||
49 | /* | 50 | /* |
50 | * Should be more than enough, but if you have a _really_ complex | 51 | * Should be more than enough, but if you have a _really_ complex |
@@ -174,8 +175,7 @@ static int __init parse_tag_mem_range(struct tag *tag, | |||
174 | * Copy the data so the bootmem init code doesn't need to care | 175 | * Copy the data so the bootmem init code doesn't need to care |
175 | * about it. | 176 | * about it. |
176 | */ | 177 | */ |
177 | if (mem_range_next_free >= | 178 | if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache)) |
178 | (sizeof(mem_range_cache) / sizeof(mem_range_cache[0]))) | ||
179 | panic("Physical memory map too complex!\n"); | 179 | panic("Physical memory map too complex!\n"); |
180 | 180 | ||
181 | new = &mem_range_cache[mem_range_next_free++]; | 181 | new = &mem_range_cache[mem_range_next_free++]; |
@@ -202,7 +202,7 @@ __tagtable(ATAG_MEM, parse_tag_mem); | |||
202 | 202 | ||
203 | static int __init parse_tag_cmdline(struct tag *tag) | 203 | static int __init parse_tag_cmdline(struct tag *tag) |
204 | { | 204 | { |
205 | strlcpy(saved_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); | 205 | strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); |
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
208 | __tagtable(ATAG_CMDLINE, parse_tag_cmdline); | 208 | __tagtable(ATAG_CMDLINE, parse_tag_cmdline); |
@@ -294,7 +294,7 @@ void __init setup_arch (char **cmdline_p) | |||
294 | init_mm.end_data = (unsigned long) &_edata; | 294 | init_mm.end_data = (unsigned long) &_edata; |
295 | init_mm.brk = (unsigned long) &_end; | 295 | init_mm.brk = (unsigned long) &_end; |
296 | 296 | ||
297 | strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); | 297 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
298 | *cmdline_p = command_line; | 298 | *cmdline_p = command_line; |
299 | parse_early_param(); | 299 | parse_early_param(); |
300 | 300 | ||
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index db8f8b55ffdf..7c279586fbba 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S | |||
@@ -8,14 +8,6 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) | ||
12 | #define sys_nfsservctl sys_ni_syscall | ||
13 | #endif | ||
14 | |||
15 | #if !defined(CONFIG_SYSV_IPC) | ||
16 | # define sys_ipc sys_ni_syscall | ||
17 | #endif | ||
18 | |||
19 | .section .rodata,"a",@progbits | 11 | .section .rodata,"a",@progbits |
20 | .type sys_call_table,@object | 12 | .type sys_call_table,@object |
21 | .global sys_call_table | 13 | .global sys_call_table |
@@ -129,7 +121,7 @@ sys_call_table: | |||
129 | .long sys_getitimer /* 105 */ | 121 | .long sys_getitimer /* 105 */ |
130 | .long sys_swapoff | 122 | .long sys_swapoff |
131 | .long sys_sysinfo | 123 | .long sys_sysinfo |
132 | .long sys_ipc | 124 | .long sys_ni_syscall /* was sys_ipc briefly */ |
133 | .long sys_sendfile | 125 | .long sys_sendfile |
134 | .long sys_setdomainname /* 110 */ | 126 | .long sys_setdomainname /* 110 */ |
135 | .long sys_newuname | 127 | .long sys_newuname |
@@ -287,4 +279,16 @@ sys_call_table: | |||
287 | .long sys_tee | 279 | .long sys_tee |
288 | .long sys_vmsplice | 280 | .long sys_vmsplice |
289 | .long __sys_epoll_pwait /* 265 */ | 281 | .long __sys_epoll_pwait /* 265 */ |
282 | .long sys_msgget | ||
283 | .long sys_msgsnd | ||
284 | .long sys_msgrcv | ||
285 | .long sys_msgctl | ||
286 | .long sys_semget /* 270 */ | ||
287 | .long sys_semop | ||
288 | .long sys_semctl | ||
289 | .long sys_semtimedop | ||
290 | .long sys_shmat | ||
291 | .long sys_shmget /* 275 */ | ||
292 | .long sys_shmdt | ||
293 | .long sys_shmctl | ||
290 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ | 294 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ |
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index 5a247ba71a72..c10833f2ee0c 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c | |||
@@ -37,7 +37,7 @@ static struct clocksource clocksource_avr32 = { | |||
37 | .read = read_cycle_count, | 37 | .read = read_cycle_count, |
38 | .mask = CLOCKSOURCE_MASK(32), | 38 | .mask = CLOCKSOURCE_MASK(32), |
39 | .shift = 16, | 39 | .shift = 16, |
40 | .is_continuous = 1, | 40 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /* | 43 | /* |
@@ -110,15 +110,6 @@ static void avr32_hpt_init(unsigned int count) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * Scheduler clock - returns current time in nanosec units. | ||
114 | */ | ||
115 | unsigned long long sched_clock(void) | ||
116 | { | ||
117 | /* There must be better ways...? */ | ||
118 | return (unsigned long long)jiffies * (1000000000 / HZ); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * local_timer_interrupt() does profiling and process accounting on a | 113 | * local_timer_interrupt() does profiling and process accounting on a |
123 | * per-CPU basis. | 114 | * per-CPU basis. |
124 | * | 115 | * |
diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c index 5c4424e362b5..ef13b7c78935 100644 --- a/arch/avr32/kernel/vmlinux.lds.c +++ b/arch/avr32/kernel/vmlinux.lds.c | |||
@@ -46,10 +46,12 @@ SECTIONS | |||
46 | __security_initcall_start = .; | 46 | __security_initcall_start = .; |
47 | *(.security_initcall.init) | 47 | *(.security_initcall.init) |
48 | __security_initcall_end = .; | 48 | __security_initcall_end = .; |
49 | #ifdef CONFIG_BLK_DEV_INITRD | ||
49 | . = ALIGN(32); | 50 | . = ALIGN(32); |
50 | __initramfs_start = .; | 51 | __initramfs_start = .; |
51 | *(.init.ramfs) | 52 | *(.init.ramfs) |
52 | __initramfs_end = .; | 53 | __initramfs_end = .; |
54 | #endif | ||
53 | . = ALIGN(4096); | 55 | . = ALIGN(4096); |
54 | __init_end = .; | 56 | __init_end = .; |
55 | } | 57 | } |
diff --git a/arch/avr32/lib/libgcc.h b/arch/avr32/lib/libgcc.h deleted file mode 100644 index 5a091b5e3618..000000000000 --- a/arch/avr32/lib/libgcc.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* Definitions for various functions 'borrowed' from gcc-3.4.3 */ | ||
2 | |||
3 | #define BITS_PER_UNIT 8 | ||
4 | |||
5 | typedef int QItype __attribute__ ((mode (QI))); | ||
6 | typedef unsigned int UQItype __attribute__ ((mode (QI))); | ||
7 | typedef int HItype __attribute__ ((mode (HI))); | ||
8 | typedef unsigned int UHItype __attribute__ ((mode (HI))); | ||
9 | typedef int SItype __attribute__ ((mode (SI))); | ||
10 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
11 | typedef int DItype __attribute__ ((mode (DI))); | ||
12 | typedef unsigned int UDItype __attribute__ ((mode (DI))); | ||
13 | typedef float SFtype __attribute__ ((mode (SF))); | ||
14 | typedef float DFtype __attribute__ ((mode (DF))); | ||
15 | typedef int word_type __attribute__ ((mode (__word__))); | ||
16 | |||
17 | #define W_TYPE_SIZE (4 * BITS_PER_UNIT) | ||
18 | #define Wtype SItype | ||
19 | #define UWtype USItype | ||
20 | #define HWtype SItype | ||
21 | #define UHWtype USItype | ||
22 | #define DWtype DItype | ||
23 | #define UDWtype UDItype | ||
24 | #define __NW(a,b) __ ## a ## si ## b | ||
25 | #define __NDW(a,b) __ ## a ## di ## b | ||
26 | |||
27 | struct DWstruct {Wtype high, low;}; | ||
28 | |||
29 | typedef union | ||
30 | { | ||
31 | struct DWstruct s; | ||
32 | DWtype ll; | ||
33 | } DWunion; | ||
diff --git a/arch/avr32/lib/longlong.h b/arch/avr32/lib/longlong.h deleted file mode 100644 index cd5e369ac437..000000000000 --- a/arch/avr32/lib/longlong.h +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. | ||
2 | Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
5 | This definition file is free software; you can redistribute it | ||
6 | and/or modify it under the terms of the GNU General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2, or (at your option) any later version. | ||
9 | |||
10 | This definition file is distributed in the hope that it will be | ||
11 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
12 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | See the GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. */ | ||
19 | |||
20 | /* Borrowed from gcc-3.4.3 */ | ||
21 | |||
22 | #define __BITS4 (W_TYPE_SIZE / 4) | ||
23 | #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) | ||
24 | #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) | ||
25 | #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) | ||
26 | |||
27 | #define count_leading_zeros(count, x) ((count) = __builtin_clz(x)) | ||
28 | |||
29 | #define __udiv_qrnnd_c(q, r, n1, n0, d) \ | ||
30 | do { \ | ||
31 | UWtype __d1, __d0, __q1, __q0; \ | ||
32 | UWtype __r1, __r0, __m; \ | ||
33 | __d1 = __ll_highpart (d); \ | ||
34 | __d0 = __ll_lowpart (d); \ | ||
35 | \ | ||
36 | __r1 = (n1) % __d1; \ | ||
37 | __q1 = (n1) / __d1; \ | ||
38 | __m = (UWtype) __q1 * __d0; \ | ||
39 | __r1 = __r1 * __ll_B | __ll_highpart (n0); \ | ||
40 | if (__r1 < __m) \ | ||
41 | { \ | ||
42 | __q1--, __r1 += (d); \ | ||
43 | if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ | ||
44 | if (__r1 < __m) \ | ||
45 | __q1--, __r1 += (d); \ | ||
46 | } \ | ||
47 | __r1 -= __m; \ | ||
48 | \ | ||
49 | __r0 = __r1 % __d1; \ | ||
50 | __q0 = __r1 / __d1; \ | ||
51 | __m = (UWtype) __q0 * __d0; \ | ||
52 | __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ | ||
53 | if (__r0 < __m) \ | ||
54 | { \ | ||
55 | __q0--, __r0 += (d); \ | ||
56 | if (__r0 >= (d)) \ | ||
57 | if (__r0 < __m) \ | ||
58 | __q0--, __r0 += (d); \ | ||
59 | } \ | ||
60 | __r0 -= __m; \ | ||
61 | \ | ||
62 | (q) = (UWtype) __q1 * __ll_B | __q0; \ | ||
63 | (r) = __r0; \ | ||
64 | } while (0) | ||
65 | |||
66 | #define udiv_qrnnd __udiv_qrnnd_c | ||
67 | |||
68 | #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ | ||
69 | do { \ | ||
70 | UWtype __x; \ | ||
71 | __x = (al) - (bl); \ | ||
72 | (sh) = (ah) - (bh) - (__x > (al)); \ | ||
73 | (sl) = __x; \ | ||
74 | } while (0) | ||
75 | |||
76 | #define umul_ppmm(w1, w0, u, v) \ | ||
77 | do { \ | ||
78 | UWtype __x0, __x1, __x2, __x3; \ | ||
79 | UHWtype __ul, __vl, __uh, __vh; \ | ||
80 | \ | ||
81 | __ul = __ll_lowpart (u); \ | ||
82 | __uh = __ll_highpart (u); \ | ||
83 | __vl = __ll_lowpart (v); \ | ||
84 | __vh = __ll_highpart (v); \ | ||
85 | \ | ||
86 | __x0 = (UWtype) __ul * __vl; \ | ||
87 | __x1 = (UWtype) __ul * __vh; \ | ||
88 | __x2 = (UWtype) __uh * __vl; \ | ||
89 | __x3 = (UWtype) __uh * __vh; \ | ||
90 | \ | ||
91 | __x1 += __ll_highpart (__x0);/* this can't give carry */ \ | ||
92 | __x1 += __x2; /* but this indeed can */ \ | ||
93 | if (__x1 < __x2) /* did we get it? */ \ | ||
94 | __x3 += __ll_B; /* yes, add it in the proper pos. */ \ | ||
95 | \ | ||
96 | (w1) = __x3 + __ll_highpart (__x1); \ | ||
97 | (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ | ||
98 | } while (0) | ||
diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile index f62eb6915510..b21bea9af8b1 100644 --- a/arch/avr32/mach-at32ap/Makefile +++ b/arch/avr32/mach-at32ap/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-y += at32ap.o clock.o pio.o intc.o extint.o hsmc.o | 1 | obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o |
2 | obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o | 2 | obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o |
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 48f4ef38c70e..bc235507c5c7 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/spi/spi.h> | ||
11 | 12 | ||
12 | #include <asm/io.h> | 13 | #include <asm/io.h> |
13 | 14 | ||
@@ -310,8 +311,6 @@ static void genclk_mode(struct clk *clk, int enabled) | |||
310 | { | 311 | { |
311 | u32 control; | 312 | u32 control; |
312 | 313 | ||
313 | BUG_ON(clk->index > 7); | ||
314 | |||
315 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); | 314 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); |
316 | if (enabled) | 315 | if (enabled) |
317 | control |= SM_BIT(CEN); | 316 | control |= SM_BIT(CEN); |
@@ -325,11 +324,6 @@ static unsigned long genclk_get_rate(struct clk *clk) | |||
325 | u32 control; | 324 | u32 control; |
326 | unsigned long div = 1; | 325 | unsigned long div = 1; |
327 | 326 | ||
328 | BUG_ON(clk->index > 7); | ||
329 | |||
330 | if (!clk->parent) | ||
331 | return 0; | ||
332 | |||
333 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); | 327 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); |
334 | if (control & SM_BIT(DIVEN)) | 328 | if (control & SM_BIT(DIVEN)) |
335 | div = 2 * (SM_BFEXT(DIV, control) + 1); | 329 | div = 2 * (SM_BFEXT(DIV, control) + 1); |
@@ -342,11 +336,6 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply) | |||
342 | u32 control; | 336 | u32 control; |
343 | unsigned long parent_rate, actual_rate, div; | 337 | unsigned long parent_rate, actual_rate, div; |
344 | 338 | ||
345 | BUG_ON(clk->index > 7); | ||
346 | |||
347 | if (!clk->parent) | ||
348 | return 0; | ||
349 | |||
350 | parent_rate = clk->parent->get_rate(clk->parent); | 339 | parent_rate = clk->parent->get_rate(clk->parent); |
351 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); | 340 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); |
352 | 341 | ||
@@ -373,11 +362,8 @@ int genclk_set_parent(struct clk *clk, struct clk *parent) | |||
373 | { | 362 | { |
374 | u32 control; | 363 | u32 control; |
375 | 364 | ||
376 | BUG_ON(clk->index > 7); | ||
377 | |||
378 | printk("clk %s: new parent %s (was %s)\n", | 365 | printk("clk %s: new parent %s (was %s)\n", |
379 | clk->name, parent->name, | 366 | clk->name, parent->name, clk->parent->name); |
380 | clk->parent ? clk->parent->name : "(null)"); | ||
381 | 367 | ||
382 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); | 368 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); |
383 | 369 | ||
@@ -399,6 +385,22 @@ int genclk_set_parent(struct clk *clk, struct clk *parent) | |||
399 | return 0; | 385 | return 0; |
400 | } | 386 | } |
401 | 387 | ||
388 | static void __init genclk_init_parent(struct clk *clk) | ||
389 | { | ||
390 | u32 control; | ||
391 | struct clk *parent; | ||
392 | |||
393 | BUG_ON(clk->index > 7); | ||
394 | |||
395 | control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); | ||
396 | if (control & SM_BIT(OSCSEL)) | ||
397 | parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1; | ||
398 | else | ||
399 | parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0; | ||
400 | |||
401 | clk->parent = parent; | ||
402 | } | ||
403 | |||
402 | /* -------------------------------------------------------------------- | 404 | /* -------------------------------------------------------------------- |
403 | * System peripherals | 405 | * System peripherals |
404 | * -------------------------------------------------------------------- */ | 406 | * -------------------------------------------------------------------- */ |
@@ -496,9 +498,16 @@ static struct resource pio3_resource[] = { | |||
496 | DEFINE_DEV(pio, 3); | 498 | DEFINE_DEV(pio, 3); |
497 | DEV_CLK(mck, pio3, pba, 13); | 499 | DEV_CLK(mck, pio3, pba, 13); |
498 | 500 | ||
501 | static struct resource pio4_resource[] = { | ||
502 | PBMEM(0xffe03800), | ||
503 | IRQ(17), | ||
504 | }; | ||
505 | DEFINE_DEV(pio, 4); | ||
506 | DEV_CLK(mck, pio4, pba, 14); | ||
507 | |||
499 | void __init at32_add_system_devices(void) | 508 | void __init at32_add_system_devices(void) |
500 | { | 509 | { |
501 | system_manager.eim_first_irq = NR_INTERNAL_IRQS; | 510 | system_manager.eim_first_irq = EIM_IRQ_BASE; |
502 | 511 | ||
503 | platform_device_register(&at32_sm_device); | 512 | platform_device_register(&at32_sm_device); |
504 | platform_device_register(&at32_intc0_device); | 513 | platform_device_register(&at32_intc0_device); |
@@ -509,6 +518,7 @@ void __init at32_add_system_devices(void) | |||
509 | platform_device_register(&pio1_device); | 518 | platform_device_register(&pio1_device); |
510 | platform_device_register(&pio2_device); | 519 | platform_device_register(&pio2_device); |
511 | platform_device_register(&pio3_device); | 520 | platform_device_register(&pio3_device); |
521 | platform_device_register(&pio4_device); | ||
512 | } | 522 | } |
513 | 523 | ||
514 | /* -------------------------------------------------------------------- | 524 | /* -------------------------------------------------------------------- |
@@ -521,7 +531,7 @@ static struct atmel_uart_data atmel_usart0_data = { | |||
521 | }; | 531 | }; |
522 | static struct resource atmel_usart0_resource[] = { | 532 | static struct resource atmel_usart0_resource[] = { |
523 | PBMEM(0xffe00c00), | 533 | PBMEM(0xffe00c00), |
524 | IRQ(7), | 534 | IRQ(6), |
525 | }; | 535 | }; |
526 | DEFINE_DEV_DATA(atmel_usart, 0); | 536 | DEFINE_DEV_DATA(atmel_usart, 0); |
527 | DEV_CLK(usart, atmel_usart0, pba, 4); | 537 | DEV_CLK(usart, atmel_usart0, pba, 4); |
@@ -583,7 +593,7 @@ static inline void configure_usart3_pins(void) | |||
583 | select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ | 593 | select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ |
584 | } | 594 | } |
585 | 595 | ||
586 | static struct platform_device *at32_usarts[4]; | 596 | static struct platform_device *__initdata at32_usarts[4]; |
587 | 597 | ||
588 | void __init at32_map_usart(unsigned int hw_id, unsigned int line) | 598 | void __init at32_map_usart(unsigned int hw_id, unsigned int line) |
589 | { | 599 | { |
@@ -728,32 +738,79 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) | |||
728 | /* -------------------------------------------------------------------- | 738 | /* -------------------------------------------------------------------- |
729 | * SPI | 739 | * SPI |
730 | * -------------------------------------------------------------------- */ | 740 | * -------------------------------------------------------------------- */ |
731 | static struct resource spi0_resource[] = { | 741 | static struct resource atmel_spi0_resource[] = { |
732 | PBMEM(0xffe00000), | 742 | PBMEM(0xffe00000), |
733 | IRQ(3), | 743 | IRQ(3), |
734 | }; | 744 | }; |
735 | DEFINE_DEV(spi, 0); | 745 | DEFINE_DEV(atmel_spi, 0); |
736 | DEV_CLK(mck, spi0, pba, 0); | 746 | DEV_CLK(spi_clk, atmel_spi0, pba, 0); |
747 | |||
748 | static struct resource atmel_spi1_resource[] = { | ||
749 | PBMEM(0xffe00400), | ||
750 | IRQ(4), | ||
751 | }; | ||
752 | DEFINE_DEV(atmel_spi, 1); | ||
753 | DEV_CLK(spi_clk, atmel_spi1, pba, 1); | ||
737 | 754 | ||
738 | struct platform_device *__init at32_add_device_spi(unsigned int id) | 755 | static void |
756 | at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, | ||
757 | unsigned int n, const u8 *pins) | ||
739 | { | 758 | { |
759 | unsigned int pin, mode; | ||
760 | |||
761 | for (; n; n--, b++) { | ||
762 | b->bus_num = bus_num; | ||
763 | if (b->chip_select >= 4) | ||
764 | continue; | ||
765 | pin = (unsigned)b->controller_data; | ||
766 | if (!pin) { | ||
767 | pin = pins[b->chip_select]; | ||
768 | b->controller_data = (void *)pin; | ||
769 | } | ||
770 | mode = AT32_GPIOF_OUTPUT; | ||
771 | if (!(b->mode & SPI_CS_HIGH)) | ||
772 | mode |= AT32_GPIOF_HIGH; | ||
773 | at32_select_gpio(pin, mode); | ||
774 | } | ||
775 | } | ||
776 | |||
777 | struct platform_device *__init | ||
778 | at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) | ||
779 | { | ||
780 | /* | ||
781 | * Manage the chipselects as GPIOs, normally using the same pins | ||
782 | * the SPI controller expects; but boards can use other pins. | ||
783 | */ | ||
784 | static u8 __initdata spi0_pins[] = | ||
785 | { GPIO_PIN_PA(3), GPIO_PIN_PA(4), | ||
786 | GPIO_PIN_PA(5), GPIO_PIN_PA(20), }; | ||
787 | static u8 __initdata spi1_pins[] = | ||
788 | { GPIO_PIN_PB(2), GPIO_PIN_PB(3), | ||
789 | GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; | ||
740 | struct platform_device *pdev; | 790 | struct platform_device *pdev; |
741 | 791 | ||
742 | switch (id) { | 792 | switch (id) { |
743 | case 0: | 793 | case 0: |
744 | pdev = &spi0_device; | 794 | pdev = &atmel_spi0_device; |
745 | select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ | 795 | select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ |
746 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ | 796 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ |
747 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ | 797 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ |
748 | select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ | 798 | at32_spi_setup_slaves(0, b, n, spi0_pins); |
749 | select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ | 799 | break; |
750 | select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ | 800 | |
801 | case 1: | ||
802 | pdev = &atmel_spi1_device; | ||
803 | select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ | ||
804 | select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ | ||
805 | select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ | ||
806 | at32_spi_setup_slaves(1, b, n, spi1_pins); | ||
751 | break; | 807 | break; |
752 | 808 | ||
753 | default: | 809 | default: |
754 | return NULL; | 810 | return NULL; |
755 | } | 811 | } |
756 | 812 | ||
813 | spi_register_board_info(b, n); | ||
757 | platform_device_register(pdev); | 814 | platform_device_register(pdev); |
758 | return pdev; | 815 | return pdev; |
759 | } | 816 | } |
@@ -837,6 +894,50 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) | |||
837 | return pdev; | 894 | return pdev; |
838 | } | 895 | } |
839 | 896 | ||
897 | /* -------------------------------------------------------------------- | ||
898 | * GCLK | ||
899 | * -------------------------------------------------------------------- */ | ||
900 | static struct clk gclk0 = { | ||
901 | .name = "gclk0", | ||
902 | .mode = genclk_mode, | ||
903 | .get_rate = genclk_get_rate, | ||
904 | .set_rate = genclk_set_rate, | ||
905 | .set_parent = genclk_set_parent, | ||
906 | .index = 0, | ||
907 | }; | ||
908 | static struct clk gclk1 = { | ||
909 | .name = "gclk1", | ||
910 | .mode = genclk_mode, | ||
911 | .get_rate = genclk_get_rate, | ||
912 | .set_rate = genclk_set_rate, | ||
913 | .set_parent = genclk_set_parent, | ||
914 | .index = 1, | ||
915 | }; | ||
916 | static struct clk gclk2 = { | ||
917 | .name = "gclk2", | ||
918 | .mode = genclk_mode, | ||
919 | .get_rate = genclk_get_rate, | ||
920 | .set_rate = genclk_set_rate, | ||
921 | .set_parent = genclk_set_parent, | ||
922 | .index = 2, | ||
923 | }; | ||
924 | static struct clk gclk3 = { | ||
925 | .name = "gclk3", | ||
926 | .mode = genclk_mode, | ||
927 | .get_rate = genclk_get_rate, | ||
928 | .set_rate = genclk_set_rate, | ||
929 | .set_parent = genclk_set_parent, | ||
930 | .index = 3, | ||
931 | }; | ||
932 | static struct clk gclk4 = { | ||
933 | .name = "gclk4", | ||
934 | .mode = genclk_mode, | ||
935 | .get_rate = genclk_get_rate, | ||
936 | .set_rate = genclk_set_rate, | ||
937 | .set_parent = genclk_set_parent, | ||
938 | .index = 4, | ||
939 | }; | ||
940 | |||
840 | struct clk *at32_clock_list[] = { | 941 | struct clk *at32_clock_list[] = { |
841 | &osc32k, | 942 | &osc32k, |
842 | &osc0, | 943 | &osc0, |
@@ -860,6 +961,7 @@ struct clk *at32_clock_list[] = { | |||
860 | &pio1_mck, | 961 | &pio1_mck, |
861 | &pio2_mck, | 962 | &pio2_mck, |
862 | &pio3_mck, | 963 | &pio3_mck, |
964 | &pio4_mck, | ||
863 | &atmel_usart0_usart, | 965 | &atmel_usart0_usart, |
864 | &atmel_usart1_usart, | 966 | &atmel_usart1_usart, |
865 | &atmel_usart2_usart, | 967 | &atmel_usart2_usart, |
@@ -868,9 +970,15 @@ struct clk *at32_clock_list[] = { | |||
868 | &macb0_pclk, | 970 | &macb0_pclk, |
869 | &macb1_hclk, | 971 | &macb1_hclk, |
870 | &macb1_pclk, | 972 | &macb1_pclk, |
871 | &spi0_mck, | 973 | &atmel_spi0_spi_clk, |
974 | &atmel_spi1_spi_clk, | ||
872 | &lcdc0_hclk, | 975 | &lcdc0_hclk, |
873 | &lcdc0_pixclk, | 976 | &lcdc0_pixclk, |
977 | &gclk0, | ||
978 | &gclk1, | ||
979 | &gclk2, | ||
980 | &gclk3, | ||
981 | &gclk4, | ||
874 | }; | 982 | }; |
875 | unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); | 983 | unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); |
876 | 984 | ||
@@ -880,6 +988,7 @@ void __init at32_portmux_init(void) | |||
880 | at32_init_pio(&pio1_device); | 988 | at32_init_pio(&pio1_device); |
881 | at32_init_pio(&pio2_device); | 989 | at32_init_pio(&pio2_device); |
882 | at32_init_pio(&pio3_device); | 990 | at32_init_pio(&pio3_device); |
991 | at32_init_pio(&pio4_device); | ||
883 | } | 992 | } |
884 | 993 | ||
885 | void __init at32_clock_init(void) | 994 | void __init at32_clock_init(void) |
@@ -898,6 +1007,13 @@ void __init at32_clock_init(void) | |||
898 | if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC)) | 1007 | if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC)) |
899 | pll1.parent = &osc1; | 1008 | pll1.parent = &osc1; |
900 | 1009 | ||
1010 | genclk_init_parent(&gclk0); | ||
1011 | genclk_init_parent(&gclk1); | ||
1012 | genclk_init_parent(&gclk2); | ||
1013 | genclk_init_parent(&gclk3); | ||
1014 | genclk_init_parent(&gclk4); | ||
1015 | genclk_init_parent(&lcdc0_pixclk); | ||
1016 | |||
901 | /* | 1017 | /* |
902 | * Turn on all clocks that have at least one user already, and | 1018 | * Turn on all clocks that have at least one user already, and |
903 | * turn off everything else. We only do this for module | 1019 | * turn off everything else. We only do this for module |
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c index ecbd4a21e432..00c435452d7e 100644 --- a/arch/avr32/mach-at32ap/clock.c +++ b/arch/avr32/mach-at32ap/clock.c | |||
@@ -63,7 +63,11 @@ EXPORT_SYMBOL(clk_enable); | |||
63 | 63 | ||
64 | static void __clk_disable(struct clk *clk) | 64 | static void __clk_disable(struct clk *clk) |
65 | { | 65 | { |
66 | BUG_ON(clk->users == 0); | 66 | if (clk->users == 0) { |
67 | printk(KERN_ERR "%s: mismatched disable\n", clk->name); | ||
68 | WARN_ON(1); | ||
69 | return; | ||
70 | } | ||
67 | 71 | ||
68 | if (--clk->users == 0 && clk->mode) | 72 | if (--clk->users == 0 && clk->mode) |
69 | clk->mode(clk, 0); | 73 | clk->mode(clk, 0); |
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index b59272e81b9a..4a60eccfebd2 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c | |||
@@ -55,20 +55,11 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) | |||
55 | unsigned long flags; | 55 | unsigned long flags; |
56 | int ret = 0; | 56 | int ret = 0; |
57 | 57 | ||
58 | flow_type &= IRQ_TYPE_SENSE_MASK; | ||
58 | if (flow_type == IRQ_TYPE_NONE) | 59 | if (flow_type == IRQ_TYPE_NONE) |
59 | flow_type = IRQ_TYPE_LEVEL_LOW; | 60 | flow_type = IRQ_TYPE_LEVEL_LOW; |
60 | 61 | ||
61 | desc = &irq_desc[irq]; | 62 | desc = &irq_desc[irq]; |
62 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | ||
63 | desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; | ||
64 | |||
65 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { | ||
66 | desc->status |= IRQ_LEVEL; | ||
67 | set_irq_handler(irq, handle_level_irq); | ||
68 | } else { | ||
69 | set_irq_handler(irq, handle_edge_irq); | ||
70 | } | ||
71 | |||
72 | spin_lock_irqsave(&sm->lock, flags); | 63 | spin_lock_irqsave(&sm->lock, flags); |
73 | 64 | ||
74 | mode = sm_readl(sm, EIM_MODE); | 65 | mode = sm_readl(sm, EIM_MODE); |
@@ -97,9 +88,16 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) | |||
97 | break; | 88 | break; |
98 | } | 89 | } |
99 | 90 | ||
100 | sm_writel(sm, EIM_MODE, mode); | 91 | if (ret == 0) { |
101 | sm_writel(sm, EIM_EDGE, edge); | 92 | sm_writel(sm, EIM_MODE, mode); |
102 | sm_writel(sm, EIM_LEVEL, level); | 93 | sm_writel(sm, EIM_EDGE, edge); |
94 | sm_writel(sm, EIM_LEVEL, level); | ||
95 | |||
96 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
97 | flow_type |= IRQ_LEVEL; | ||
98 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | ||
99 | desc->status |= flow_type; | ||
100 | } | ||
103 | 101 | ||
104 | spin_unlock_irqrestore(&sm->lock, flags); | 102 | spin_unlock_irqrestore(&sm->lock, flags); |
105 | 103 | ||
@@ -122,8 +120,6 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) | |||
122 | unsigned long status, pending; | 120 | unsigned long status, pending; |
123 | unsigned int i, ext_irq; | 121 | unsigned int i, ext_irq; |
124 | 122 | ||
125 | spin_lock(&sm->lock); | ||
126 | |||
127 | status = sm_readl(sm, EIM_ISR); | 123 | status = sm_readl(sm, EIM_ISR); |
128 | pending = status & sm_readl(sm, EIM_IMR); | 124 | pending = status & sm_readl(sm, EIM_IMR); |
129 | 125 | ||
@@ -133,10 +129,11 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) | |||
133 | 129 | ||
134 | ext_irq = i + sm->eim_first_irq; | 130 | ext_irq = i + sm->eim_first_irq; |
135 | ext_desc = irq_desc + ext_irq; | 131 | ext_desc = irq_desc + ext_irq; |
136 | ext_desc->handle_irq(ext_irq, ext_desc); | 132 | if (ext_desc->status & IRQ_LEVEL) |
133 | handle_level_irq(ext_irq, ext_desc); | ||
134 | else | ||
135 | handle_edge_irq(ext_irq, ext_desc); | ||
137 | } | 136 | } |
138 | |||
139 | spin_unlock(&sm->lock); | ||
140 | } | 137 | } |
141 | 138 | ||
142 | static int __init eim_init(void) | 139 | static int __init eim_init(void) |
@@ -168,8 +165,9 @@ static int __init eim_init(void) | |||
168 | sm->eim_chip = &eim_chip; | 165 | sm->eim_chip = &eim_chip; |
169 | 166 | ||
170 | for (i = 0; i < nr_irqs; i++) { | 167 | for (i = 0; i < nr_irqs; i++) { |
168 | /* NOTE the handler we set here is ignored by the demux */ | ||
171 | set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, | 169 | set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, |
172 | handle_edge_irq); | 170 | handle_level_irq); |
173 | set_irq_chip_data(sm->eim_first_irq + i, sm); | 171 | set_irq_chip_data(sm->eim_first_irq + i, sm); |
174 | } | 172 | } |
175 | 173 | ||
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index f1280ed8ed6d..9ba5654cde11 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c | |||
@@ -12,7 +12,9 @@ | |||
12 | #include <linux/debugfs.h> | 12 | #include <linux/debugfs.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/irq.h> | ||
15 | 16 | ||
17 | #include <asm/gpio.h> | ||
16 | #include <asm/io.h> | 18 | #include <asm/io.h> |
17 | 19 | ||
18 | #include <asm/arch/portmux.h> | 20 | #include <asm/arch/portmux.h> |
@@ -26,7 +28,8 @@ struct pio_device { | |||
26 | const struct platform_device *pdev; | 28 | const struct platform_device *pdev; |
27 | struct clk *clk; | 29 | struct clk *clk; |
28 | u32 pinmux_mask; | 30 | u32 pinmux_mask; |
29 | char name[32]; | 31 | u32 gpio_mask; |
32 | char name[8]; | ||
30 | }; | 33 | }; |
31 | 34 | ||
32 | static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; | 35 | static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; |
@@ -76,6 +79,9 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph, | |||
76 | if (!(flags & AT32_GPIOF_PULLUP)) | 79 | if (!(flags & AT32_GPIOF_PULLUP)) |
77 | pio_writel(pio, PUDR, mask); | 80 | pio_writel(pio, PUDR, mask); |
78 | 81 | ||
82 | /* gpio_request NOT allowed */ | ||
83 | set_bit(pin_index, &pio->gpio_mask); | ||
84 | |||
79 | return; | 85 | return; |
80 | 86 | ||
81 | fail: | 87 | fail: |
@@ -99,19 +105,52 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags) | |||
99 | goto fail; | 105 | goto fail; |
100 | } | 106 | } |
101 | 107 | ||
102 | pio_writel(pio, PUER, mask); | 108 | if (flags & AT32_GPIOF_OUTPUT) { |
103 | if (flags & AT32_GPIOF_HIGH) | 109 | if (flags & AT32_GPIOF_HIGH) |
104 | pio_writel(pio, SODR, mask); | 110 | pio_writel(pio, SODR, mask); |
105 | else | 111 | else |
106 | pio_writel(pio, CODR, mask); | 112 | pio_writel(pio, CODR, mask); |
107 | if (flags & AT32_GPIOF_OUTPUT) | 113 | pio_writel(pio, PUDR, mask); |
108 | pio_writel(pio, OER, mask); | 114 | pio_writel(pio, OER, mask); |
109 | else | 115 | } else { |
116 | if (flags & AT32_GPIOF_PULLUP) | ||
117 | pio_writel(pio, PUER, mask); | ||
118 | else | ||
119 | pio_writel(pio, PUDR, mask); | ||
120 | if (flags & AT32_GPIOF_DEGLITCH) | ||
121 | pio_writel(pio, IFER, mask); | ||
122 | else | ||
123 | pio_writel(pio, IFDR, mask); | ||
110 | pio_writel(pio, ODR, mask); | 124 | pio_writel(pio, ODR, mask); |
125 | } | ||
111 | 126 | ||
112 | pio_writel(pio, PER, mask); | 127 | pio_writel(pio, PER, mask); |
113 | if (!(flags & AT32_GPIOF_PULLUP)) | 128 | |
114 | pio_writel(pio, PUDR, mask); | 129 | /* gpio_request now allowed */ |
130 | clear_bit(pin_index, &pio->gpio_mask); | ||
131 | |||
132 | return; | ||
133 | |||
134 | fail: | ||
135 | dump_stack(); | ||
136 | } | ||
137 | |||
138 | /* Reserve a pin, preventing anyone else from changing its configuration. */ | ||
139 | void __init at32_reserve_pin(unsigned int pin) | ||
140 | { | ||
141 | struct pio_device *pio; | ||
142 | unsigned int pin_index = pin & 0x1f; | ||
143 | |||
144 | pio = gpio_to_pio(pin); | ||
145 | if (unlikely(!pio)) { | ||
146 | printk("pio: invalid pin %u\n", pin); | ||
147 | goto fail; | ||
148 | } | ||
149 | |||
150 | if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { | ||
151 | printk("%s: pin %u is busy\n", pio->name, pin_index); | ||
152 | goto fail; | ||
153 | } | ||
115 | 154 | ||
116 | return; | 155 | return; |
117 | 156 | ||
@@ -119,20 +158,197 @@ fail: | |||
119 | dump_stack(); | 158 | dump_stack(); |
120 | } | 159 | } |
121 | 160 | ||
161 | /*--------------------------------------------------------------------------*/ | ||
162 | |||
163 | /* GPIO API */ | ||
164 | |||
165 | int gpio_request(unsigned int gpio, const char *label) | ||
166 | { | ||
167 | struct pio_device *pio; | ||
168 | unsigned int pin; | ||
169 | |||
170 | pio = gpio_to_pio(gpio); | ||
171 | if (!pio) | ||
172 | return -ENODEV; | ||
173 | |||
174 | pin = gpio & 0x1f; | ||
175 | if (test_and_set_bit(pin, &pio->gpio_mask)) | ||
176 | return -EBUSY; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | EXPORT_SYMBOL(gpio_request); | ||
181 | |||
182 | void gpio_free(unsigned int gpio) | ||
183 | { | ||
184 | struct pio_device *pio; | ||
185 | unsigned int pin; | ||
186 | |||
187 | pio = gpio_to_pio(gpio); | ||
188 | if (!pio) { | ||
189 | printk(KERN_ERR | ||
190 | "gpio: attempted to free invalid pin %u\n", gpio); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | pin = gpio & 0x1f; | ||
195 | if (!test_and_clear_bit(pin, &pio->gpio_mask)) | ||
196 | printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n", | ||
197 | pio->name, pin); | ||
198 | } | ||
199 | EXPORT_SYMBOL(gpio_free); | ||
200 | |||
201 | int gpio_direction_input(unsigned int gpio) | ||
202 | { | ||
203 | struct pio_device *pio; | ||
204 | unsigned int pin; | ||
205 | |||
206 | pio = gpio_to_pio(gpio); | ||
207 | if (!pio) | ||
208 | return -ENODEV; | ||
209 | |||
210 | pin = gpio & 0x1f; | ||
211 | pio_writel(pio, ODR, 1 << pin); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | EXPORT_SYMBOL(gpio_direction_input); | ||
216 | |||
217 | int gpio_direction_output(unsigned int gpio) | ||
218 | { | ||
219 | struct pio_device *pio; | ||
220 | unsigned int pin; | ||
221 | |||
222 | pio = gpio_to_pio(gpio); | ||
223 | if (!pio) | ||
224 | return -ENODEV; | ||
225 | |||
226 | pin = gpio & 0x1f; | ||
227 | pio_writel(pio, OER, 1 << pin); | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | EXPORT_SYMBOL(gpio_direction_output); | ||
232 | |||
233 | int gpio_get_value(unsigned int gpio) | ||
234 | { | ||
235 | struct pio_device *pio = &pio_dev[gpio >> 5]; | ||
236 | |||
237 | return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1; | ||
238 | } | ||
239 | EXPORT_SYMBOL(gpio_get_value); | ||
240 | |||
241 | void gpio_set_value(unsigned int gpio, int value) | ||
242 | { | ||
243 | struct pio_device *pio = &pio_dev[gpio >> 5]; | ||
244 | u32 mask; | ||
245 | |||
246 | mask = 1 << (gpio & 0x1f); | ||
247 | if (value) | ||
248 | pio_writel(pio, SODR, mask); | ||
249 | else | ||
250 | pio_writel(pio, CODR, mask); | ||
251 | } | ||
252 | EXPORT_SYMBOL(gpio_set_value); | ||
253 | |||
254 | /*--------------------------------------------------------------------------*/ | ||
255 | |||
256 | /* GPIO IRQ support */ | ||
257 | |||
258 | static void gpio_irq_mask(unsigned irq) | ||
259 | { | ||
260 | unsigned gpio = irq_to_gpio(irq); | ||
261 | struct pio_device *pio = &pio_dev[gpio >> 5]; | ||
262 | |||
263 | pio_writel(pio, IDR, 1 << (gpio & 0x1f)); | ||
264 | } | ||
265 | |||
266 | static void gpio_irq_unmask(unsigned irq) | ||
267 | { | ||
268 | unsigned gpio = irq_to_gpio(irq); | ||
269 | struct pio_device *pio = &pio_dev[gpio >> 5]; | ||
270 | |||
271 | pio_writel(pio, IER, 1 << (gpio & 0x1f)); | ||
272 | } | ||
273 | |||
274 | static int gpio_irq_type(unsigned irq, unsigned type) | ||
275 | { | ||
276 | if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) | ||
277 | return -EINVAL; | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static struct irq_chip gpio_irqchip = { | ||
283 | .name = "gpio", | ||
284 | .mask = gpio_irq_mask, | ||
285 | .unmask = gpio_irq_unmask, | ||
286 | .set_type = gpio_irq_type, | ||
287 | }; | ||
288 | |||
289 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
290 | { | ||
291 | struct pio_device *pio = get_irq_chip_data(irq); | ||
292 | unsigned gpio_irq; | ||
293 | |||
294 | gpio_irq = (unsigned) get_irq_data(irq); | ||
295 | for (;;) { | ||
296 | u32 isr; | ||
297 | struct irq_desc *d; | ||
298 | |||
299 | /* ack pending GPIO interrupts */ | ||
300 | isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); | ||
301 | if (!isr) | ||
302 | break; | ||
303 | do { | ||
304 | int i; | ||
305 | |||
306 | i = ffs(isr) - 1; | ||
307 | isr &= ~(1 << i); | ||
308 | |||
309 | i += gpio_irq; | ||
310 | d = &irq_desc[i]; | ||
311 | |||
312 | d->handle_irq(i, d); | ||
313 | } while (isr); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | static void __init | ||
318 | gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) | ||
319 | { | ||
320 | unsigned i; | ||
321 | |||
322 | set_irq_chip_data(irq, pio); | ||
323 | set_irq_data(irq, (void *) gpio_irq); | ||
324 | |||
325 | for (i = 0; i < 32; i++, gpio_irq++) { | ||
326 | set_irq_chip_data(gpio_irq, pio); | ||
327 | set_irq_chip_and_handler(gpio_irq, &gpio_irqchip, | ||
328 | handle_simple_irq); | ||
329 | } | ||
330 | |||
331 | set_irq_chained_handler(irq, gpio_irq_handler); | ||
332 | } | ||
333 | |||
334 | /*--------------------------------------------------------------------------*/ | ||
335 | |||
122 | static int __init pio_probe(struct platform_device *pdev) | 336 | static int __init pio_probe(struct platform_device *pdev) |
123 | { | 337 | { |
124 | struct pio_device *pio = NULL; | 338 | struct pio_device *pio = NULL; |
339 | int irq = platform_get_irq(pdev, 0); | ||
340 | int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32; | ||
125 | 341 | ||
126 | BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); | 342 | BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); |
127 | pio = &pio_dev[pdev->id]; | 343 | pio = &pio_dev[pdev->id]; |
128 | BUG_ON(!pio->regs); | 344 | BUG_ON(!pio->regs); |
129 | 345 | ||
130 | /* TODO: Interrupts */ | 346 | gpio_irq_setup(pio, irq, gpio_irq_base); |
131 | 347 | ||
132 | platform_set_drvdata(pdev, pio); | 348 | platform_set_drvdata(pdev, pio); |
133 | 349 | ||
134 | printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n", | 350 | printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n", |
135 | pio->name, pio->regs, platform_get_irq(pdev, 0)); | 351 | pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31); |
136 | 352 | ||
137 | return 0; | 353 | return 0; |
138 | } | 354 | } |
@@ -148,7 +364,7 @@ static int __init pio_init(void) | |||
148 | { | 364 | { |
149 | return platform_driver_register(&pio_driver); | 365 | return platform_driver_register(&pio_driver); |
150 | } | 366 | } |
151 | subsys_initcall(pio_init); | 367 | postcore_initcall(pio_init); |
152 | 368 | ||
153 | void __init at32_init_pio(struct platform_device *pdev) | 369 | void __init at32_init_pio(struct platform_device *pdev) |
154 | { | 370 | { |
@@ -184,6 +400,13 @@ void __init at32_init_pio(struct platform_device *pdev) | |||
184 | pio->pdev = pdev; | 400 | pio->pdev = pdev; |
185 | pio->regs = ioremap(regs->start, regs->end - regs->start + 1); | 401 | pio->regs = ioremap(regs->start, regs->end - regs->start + 1); |
186 | 402 | ||
187 | pio_writel(pio, ODR, ~0UL); | 403 | /* |
188 | pio_writel(pio, PER, ~0UL); | 404 | * request_gpio() is only valid for pins that have been |
405 | * explicitly configured as GPIO and not previously requested | ||
406 | */ | ||
407 | pio->gpio_mask = ~0UL; | ||
408 | |||
409 | /* start with irqs disabled and acked */ | ||
410 | pio_writel(pio, IDR, ~0UL); | ||
411 | (void) pio_readl(pio, ISR); | ||
189 | } | 412 | } |
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c index 450515b245a0..fb13f72e9a02 100644 --- a/arch/avr32/mm/cache.c +++ b/arch/avr32/mm/cache.c | |||
@@ -22,18 +22,34 @@ | |||
22 | 22 | ||
23 | void invalidate_dcache_region(void *start, size_t size) | 23 | void invalidate_dcache_region(void *start, size_t size) |
24 | { | 24 | { |
25 | unsigned long v, begin, end, linesz; | 25 | unsigned long v, begin, end, linesz, mask; |
26 | int flush = 0; | ||
26 | 27 | ||
27 | linesz = boot_cpu_data.dcache.linesz; | 28 | linesz = boot_cpu_data.dcache.linesz; |
29 | mask = linesz - 1; | ||
30 | |||
31 | /* when first and/or last cachelines are shared, flush them | ||
32 | * instead of invalidating ... never discard valid data! | ||
33 | */ | ||
34 | begin = (unsigned long)start; | ||
35 | end = begin + size - 1; | ||
36 | |||
37 | if (begin & mask) { | ||
38 | flush_dcache_line(start); | ||
39 | begin += linesz; | ||
40 | flush = 1; | ||
41 | } | ||
42 | if ((end & mask) != mask) { | ||
43 | flush_dcache_line((void *)end); | ||
44 | end -= linesz; | ||
45 | flush = 1; | ||
46 | } | ||
28 | 47 | ||
29 | //printk("invalidate dcache: %p + %u\n", start, size); | 48 | /* remaining cachelines only need invalidation */ |
30 | 49 | for (v = begin; v <= end; v += linesz) | |
31 | /* You asked for it, you got it */ | ||
32 | begin = (unsigned long)start & ~(linesz - 1); | ||
33 | end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); | ||
34 | |||
35 | for (v = begin; v < end; v += linesz) | ||
36 | invalidate_dcache_line((void *)v); | 50 | invalidate_dcache_line((void *)v); |
51 | if (flush) | ||
52 | flush_write_buffer(); | ||
37 | } | 53 | } |
38 | 54 | ||
39 | void clean_dcache_region(void *start, size_t size) | 55 | void clean_dcache_region(void *start, size_t size) |
diff --git a/arch/avr32/mm/tlb.c b/arch/avr32/mm/tlb.c index 7b073052203d..56672018e42f 100644 --- a/arch/avr32/mm/tlb.c +++ b/arch/avr32/mm/tlb.c | |||
@@ -360,7 +360,7 @@ static int tlb_open(struct inode *inode, struct file *file) | |||
360 | return seq_open(file, &tlb_ops); | 360 | return seq_open(file, &tlb_ops); |
361 | } | 361 | } |
362 | 362 | ||
363 | static struct file_operations proc_tlb_operations = { | 363 | static const struct file_operations proc_tlb_operations = { |
364 | .open = tlb_open, | 364 | .open = tlb_open, |
365 | .read = seq_read, | 365 | .read = seq_read, |
366 | .llseek = seq_lseek, | 366 | .llseek = seq_lseek, |