aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-18 15:57:52 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-18 15:57:52 -0400
commit5bae7ac9feba925fd0099057f6b23d7be80b7b41 (patch)
tree7ff78cda1d18a7b5eb5c6384815bb8f7b87cf5ce
parent97405fe26b2a4df7090884b086ee8224ace2a6d1 (diff)
parent587ca7619a150cef0ce0dd8fd08c367e502f0421 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: [AVR32] Initialize phy_mask for both macb devices [AVR32] Fix atomic_add_unless() and atomic_sub_unless() [AVR32] Correct misspelled CONFIG_BLK_DEV_INITRD variable. [AVR32] Fix build error in parse_tag_rdimg() [AVR32] Don't wire up macb0 unless SW6 is in default position [AVR32] Wire up SSC platform device 0 as TX on ATSTK1000 board [AVR32] Add Atmel SSC driver platform device to AT32AP architecture [AVR32] Remove optimization of unaligned word loads [AVR32] Make STK1000 mux settings configurable [AVR32] CPU frequency scaling for AT32AP [AVR32] Split SM device into PM, RTC, WDT and EIC [AVR32] faster avr32 unaligned access
-rw-r--r--arch/avr32/Kconfig25
-rw-r--r--arch/avr32/boards/atstk1000/Kconfig53
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c50
-rw-r--r--arch/avr32/kernel/setup.c4
-rw-r--r--arch/avr32/mach-at32ap/Makefile1
-rw-r--r--arch/avr32/mach-at32ap/at32ap.c31
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c340
-rw-r--r--arch/avr32/mach-at32ap/cpufreq.c112
-rw-r--r--arch/avr32/mach-at32ap/extint.c200
-rw-r--r--arch/avr32/mach-at32ap/pm.h112
-rw-r--r--arch/avr32/mach-at32ap/sm.h242
-rw-r--r--include/asm-avr32/arch-at32ap/board.h14
-rw-r--r--include/asm-avr32/arch-at32ap/sm.h27
-rw-r--r--include/asm-avr32/atomic.h4
-rw-r--r--include/asm-avr32/unaligned.h15
15 files changed, 751 insertions, 479 deletions
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 3ec76586877..d12346aaa88 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -113,6 +113,10 @@ config BOARD_ATNGW100
113 bool "ATNGW100 Network Gateway" 113 bool "ATNGW100 Network Gateway"
114endchoice 114endchoice
115 115
116if BOARD_ATSTK1000
117source "arch/avr32/boards/atstk1000/Kconfig"
118endif
119
116choice 120choice
117 prompt "Boot loader type" 121 prompt "Boot loader type"
118 default LOADER_U_BOOT 122 default LOADER_U_BOOT
@@ -185,6 +189,27 @@ config CMDLINE
185 189
186endmenu 190endmenu
187 191
192menu "Power managment options"
193
194menu "CPU Frequency scaling"
195
196source "drivers/cpufreq/Kconfig"
197
198config CPU_FREQ_AT32AP
199 bool "CPU frequency driver for AT32AP"
200 depends on CPU_FREQ && PLATFORM_AT32AP
201 default n
202 help
203 This enables the CPU frequency driver for AT32AP processors.
204
205 For details, take a look in <file:Documentation/cpu-freq>.
206
207 If in doubt, say N.
208
209endmenu
210
211endmenu
212
188menu "Bus options" 213menu "Bus options"
189 214
190config PCI 215config PCI
diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig
new file mode 100644
index 00000000000..71bc7d364fb
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/Kconfig
@@ -0,0 +1,53 @@
1# STK1000 customization
2
3if BOARD_ATSTK1002
4
5config BOARD_ATSTK1002_CUSTOM
6 bool "Non-default STK-1002 jumper settings"
7 help
8 You will normally leave the jumpers on the CPU card at their
9 default settings. If you need to use certain peripherals,
10 you will need to change some of those jumpers.
11
12if BOARD_ATSTK1002_CUSTOM
13
14config BOARD_ATSTK1002_SW1_CUSTOM
15 bool "SW1: use SSC1 (not SPI0)"
16 help
17 This also prevents using the external DAC as an audio interface,
18 and means you can't initialize the on-board QVGA display.
19
20config BOARD_ATSTK1002_SW2_CUSTOM
21 bool "SW2: use IRDA or TIMER0 (not UART-A, MMC/SD, and PS2-A)"
22 help
23 If you change this you'll want an updated boot loader putting
24 the console on UART-C not UART-A.
25
26config BOARD_ATSTK1002_SW3_CUSTOM
27 bool "SW3: use TIMER1 (not SSC0 and GCLK)"
28 help
29 This also prevents using the external DAC as an audio interface.
30
31config BOARD_ATSTK1002_SW4_CUSTOM
32 bool "SW4: use ISI/Camera (not GPIOs, SPI1, and PS2-B)"
33 help
34 To use the camera interface you'll need a custom card (on the
35 PCI-format connector) connect a video sensor.
36
37config BOARD_ATSTK1002_SW5_CUSTOM
38 bool "SW5: use MACB1 (not LCDC)"
39
40config BOARD_ATSTK1002_SW6_CUSTOM
41 bool "SW6: more GPIOs (not MACB0)"
42
43endif # custom
44
45config BOARD_ATSTK1002_SPI1
46 bool "Configure SPI1 controller"
47 depends on !BOARD_ATSTK1002_SW4_CUSTOM
48 help
49 All the signals for the second SPI controller are available on
50 GPIO lines and accessed through the J1 jumper block. Say "y"
51 here to configure that SPI controller.
52
53endif # stk 1002
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index e253e86a1a3..cb93eabb9c6 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -27,15 +27,27 @@
27 27
28#include "atstk1000.h" 28#include "atstk1000.h"
29 29
30#define SW2_DEFAULT /* MMCI and UART_A available */
31 30
32struct eth_addr { 31struct eth_addr {
33 u8 addr[6]; 32 u8 addr[6];
34}; 33};
35 34
36static struct eth_addr __initdata hw_addr[2]; 35static struct eth_addr __initdata hw_addr[2];
37static struct eth_platform_data __initdata eth_data[2]; 36static struct eth_platform_data __initdata eth_data[2] = {
37 {
38 /*
39 * The MDIO pullups on STK1000 are a bit too weak for
40 * the autodetection to work properly, so we have to
41 * mask out everything but the correct address.
42 */
43 .phy_mask = ~(1U << 16),
44 },
45 {
46 .phy_mask = ~(1U << 17),
47 },
48};
38 49
50#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
39static struct spi_board_info spi0_board_info[] __initdata = { 51static struct spi_board_info spi0_board_info[] __initdata = {
40 { 52 {
41 /* QVGA display */ 53 /* QVGA display */
@@ -45,6 +57,13 @@ static struct spi_board_info spi0_board_info[] __initdata = {
45 .mode = SPI_MODE_3, 57 .mode = SPI_MODE_3,
46 }, 58 },
47}; 59};
60#endif
61
62#ifdef CONFIG_BOARD_ATSTK1002_SPI1
63static struct spi_board_info spi1_board_info[] __initdata = { {
64 /* patch in custom entries here */
65} };
66#endif
48 67
49/* 68/*
50 * The next two functions should go away as the boot loader is 69 * The next two functions should go away as the boot loader is
@@ -103,10 +122,10 @@ static void __init set_hw_addr(struct platform_device *pdev)
103 122
104void __init setup_board(void) 123void __init setup_board(void)
105{ 124{
106#ifdef SW2_DEFAULT 125#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
107 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
108#else
109 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ 126 at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
127#else
128 at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
110#endif 129#endif
111 /* USART 2/unused: expansion connector */ 130 /* USART 2/unused: expansion connector */
112 at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */ 131 at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
@@ -140,18 +159,31 @@ static int __init atstk1002_init(void)
140 159
141 at32_add_system_devices(); 160 at32_add_system_devices();
142 161
143#ifdef SW2_DEFAULT 162#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
144 at32_add_device_usart(0);
145#else
146 at32_add_device_usart(1); 163 at32_add_device_usart(1);
164#else
165 at32_add_device_usart(0);
147#endif 166#endif
148 at32_add_device_usart(2); 167 at32_add_device_usart(2);
149 168
169#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
150 set_hw_addr(at32_add_device_eth(0, &eth_data[0])); 170 set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
151 171#endif
172#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
152 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); 173 at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
174#endif
175#ifdef CONFIG_BOARD_ATSTK1002_SPI1
176 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
177#endif
178#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
179 set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
180#else
153 at32_add_device_lcdc(0, &atstk1000_lcdc_data, 181 at32_add_device_lcdc(0, &atstk1000_lcdc_data,
154 fbmem_start, fbmem_size); 182 fbmem_start, fbmem_size);
183#endif
184#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
185 at32_add_device_ssc(0, ATMEL_SSC_TX);
186#endif
155 187
156 return 0; 188 return 0;
157} 189}
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c
index b279d66acf5..d08b0bc6b2b 100644
--- a/arch/avr32/kernel/setup.c
+++ b/arch/avr32/kernel/setup.c
@@ -313,7 +313,7 @@ __tagtable(ATAG_MEM, parse_tag_mem);
313 313
314static int __init parse_tag_rdimg(struct tag *tag) 314static int __init parse_tag_rdimg(struct tag *tag)
315{ 315{
316#ifdef CONFIG_INITRD 316#ifdef CONFIG_BLK_DEV_INITRD
317 struct tag_mem_range *mem = &tag->u.mem_range; 317 struct tag_mem_range *mem = &tag->u.mem_range;
318 int ret; 318 int ret;
319 319
@@ -323,7 +323,7 @@ static int __init parse_tag_rdimg(struct tag *tag)
323 return 0; 323 return 0;
324 } 324 }
325 325
326 ret = add_reserved_region(mem->start, mem->start + mem->size - 1, 326 ret = add_reserved_region(mem->addr, mem->addr + mem->size - 1,
327 "initrd"); 327 "initrd");
328 if (ret) { 328 if (ret) {
329 printk(KERN_WARNING 329 printk(KERN_WARNING
diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile
index f1d395724ac..a8b445046e3 100644
--- a/arch/avr32/mach-at32ap/Makefile
+++ b/arch/avr32/mach-at32ap/Makefile
@@ -1,3 +1,4 @@
1obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o 1obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o
2obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o 2obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o
3obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o 3obj-$(CONFIG_CPU_AT32AP7000) += time-tc.o
4obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o
diff --git a/arch/avr32/mach-at32ap/at32ap.c b/arch/avr32/mach-at32ap/at32ap.c
index 90f207e8e96..7c4987f3287 100644
--- a/arch/avr32/mach-at32ap/at32ap.c
+++ b/arch/avr32/mach-at32ap/at32ap.c
@@ -11,41 +11,10 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13 13
14#include <asm/io.h>
15
16#include <asm/arch/init.h> 14#include <asm/arch/init.h>
17#include <asm/arch/sm.h>
18
19struct at32_sm system_manager;
20
21static int __init at32_sm_init(void)
22{
23 struct resource *regs;
24 struct at32_sm *sm = &system_manager;
25 int ret = -ENXIO;
26
27 regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0);
28 if (!regs)
29 goto fail;
30
31 spin_lock_init(&sm->lock);
32 sm->pdev = &at32_sm_device;
33
34 ret = -ENOMEM;
35 sm->regs = ioremap(regs->start, regs->end - regs->start + 1);
36 if (!sm->regs)
37 goto fail;
38
39 return 0;
40
41fail:
42 printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret);
43 return ret;
44}
45 15
46void __init setup_platform(void) 16void __init setup_platform(void)
47{ 17{
48 at32_sm_init();
49 at32_clock_init(); 18 at32_clock_init();
50 at32_portmux_init(); 19 at32_portmux_init();
51} 20}
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index 4dda42d3f6d..64cc5583ddf 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -17,14 +17,20 @@
17#include <asm/arch/at32ap7000.h> 17#include <asm/arch/at32ap7000.h>
18#include <asm/arch/board.h> 18#include <asm/arch/board.h>
19#include <asm/arch/portmux.h> 19#include <asm/arch/portmux.h>
20#include <asm/arch/sm.h>
21 20
22#include <video/atmel_lcdc.h> 21#include <video/atmel_lcdc.h>
23 22
24#include "clock.h" 23#include "clock.h"
25#include "hmatrix.h" 24#include "hmatrix.h"
26#include "pio.h" 25#include "pio.h"
27#include "sm.h" 26#include "pm.h"
27
28/*
29 * We can reduce the code size a bit by using a constant here. Since
30 * this file is completely chip-specific, it's safe to not use
31 * ioremap. Generic drivers should of course never do this.
32 */
33#define AT32_PM_BASE 0xfff00000
28 34
29#define PBMEM(base) \ 35#define PBMEM(base) \
30 { \ 36 { \
@@ -88,6 +94,8 @@ static struct clk devname##_##_name = { \
88 .index = _index, \ 94 .index = _index, \
89} 95}
90 96
97static DEFINE_SPINLOCK(pm_lock);
98
91unsigned long at32ap7000_osc_rates[3] = { 99unsigned long at32ap7000_osc_rates[3] = {
92 [0] = 32768, 100 [0] = 32768,
93 /* FIXME: these are ATSTK1002-specific */ 101 /* FIXME: these are ATSTK1002-specific */
@@ -104,11 +112,11 @@ static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
104{ 112{
105 unsigned long div, mul, rate; 113 unsigned long div, mul, rate;
106 114
107 if (!(control & SM_BIT(PLLEN))) 115 if (!(control & PM_BIT(PLLEN)))
108 return 0; 116 return 0;
109 117
110 div = SM_BFEXT(PLLDIV, control) + 1; 118 div = PM_BFEXT(PLLDIV, control) + 1;
111 mul = SM_BFEXT(PLLMUL, control) + 1; 119 mul = PM_BFEXT(PLLMUL, control) + 1;
112 120
113 rate = clk->parent->get_rate(clk->parent); 121 rate = clk->parent->get_rate(clk->parent);
114 rate = (rate + div / 2) / div; 122 rate = (rate + div / 2) / div;
@@ -121,7 +129,7 @@ static unsigned long pll0_get_rate(struct clk *clk)
121{ 129{
122 u32 control; 130 u32 control;
123 131
124 control = sm_readl(&system_manager, PM_PLL0); 132 control = pm_readl(PLL0);
125 133
126 return pll_get_rate(clk, control); 134 return pll_get_rate(clk, control);
127} 135}
@@ -130,7 +138,7 @@ static unsigned long pll1_get_rate(struct clk *clk)
130{ 138{
131 u32 control; 139 u32 control;
132 140
133 control = sm_readl(&system_manager, PM_PLL1); 141 control = pm_readl(PLL1);
134 142
135 return pll_get_rate(clk, control); 143 return pll_get_rate(clk, control);
136} 144}
@@ -187,108 +195,139 @@ static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)
187 195
188static void cpu_clk_mode(struct clk *clk, int enabled) 196static void cpu_clk_mode(struct clk *clk, int enabled)
189{ 197{
190 struct at32_sm *sm = &system_manager;
191 unsigned long flags; 198 unsigned long flags;
192 u32 mask; 199 u32 mask;
193 200
194 spin_lock_irqsave(&sm->lock, flags); 201 spin_lock_irqsave(&pm_lock, flags);
195 mask = sm_readl(sm, PM_CPU_MASK); 202 mask = pm_readl(CPU_MASK);
196 if (enabled) 203 if (enabled)
197 mask |= 1 << clk->index; 204 mask |= 1 << clk->index;
198 else 205 else
199 mask &= ~(1 << clk->index); 206 mask &= ~(1 << clk->index);
200 sm_writel(sm, PM_CPU_MASK, mask); 207 pm_writel(CPU_MASK, mask);
201 spin_unlock_irqrestore(&sm->lock, flags); 208 spin_unlock_irqrestore(&pm_lock, flags);
202} 209}
203 210
204static unsigned long cpu_clk_get_rate(struct clk *clk) 211static unsigned long cpu_clk_get_rate(struct clk *clk)
205{ 212{
206 unsigned long cksel, shift = 0; 213 unsigned long cksel, shift = 0;
207 214
208 cksel = sm_readl(&system_manager, PM_CKSEL); 215 cksel = pm_readl(CKSEL);
209 if (cksel & SM_BIT(CPUDIV)) 216 if (cksel & PM_BIT(CPUDIV))
210 shift = SM_BFEXT(CPUSEL, cksel) + 1; 217 shift = PM_BFEXT(CPUSEL, cksel) + 1;
211 218
212 return bus_clk_get_rate(clk, shift); 219 return bus_clk_get_rate(clk, shift);
213} 220}
214 221
222static long cpu_clk_set_rate(struct clk *clk, unsigned long rate, int apply)
223{
224 u32 control;
225 unsigned long parent_rate, child_div, actual_rate, div;
226
227 parent_rate = clk->parent->get_rate(clk->parent);
228 control = pm_readl(CKSEL);
229
230 if (control & PM_BIT(HSBDIV))
231 child_div = 1 << (PM_BFEXT(HSBSEL, control) + 1);
232 else
233 child_div = 1;
234
235 if (rate > 3 * (parent_rate / 4) || child_div == 1) {
236 actual_rate = parent_rate;
237 control &= ~PM_BIT(CPUDIV);
238 } else {
239 unsigned int cpusel;
240 div = (parent_rate + rate / 2) / rate;
241 if (div > child_div)
242 div = child_div;
243 cpusel = (div > 1) ? (fls(div) - 2) : 0;
244 control = PM_BIT(CPUDIV) | PM_BFINS(CPUSEL, cpusel, control);
245 actual_rate = parent_rate / (1 << (cpusel + 1));
246 }
247
248 pr_debug("clk %s: new rate %lu (actual rate %lu)\n",
249 clk->name, rate, actual_rate);
250
251 if (apply)
252 pm_writel(CKSEL, control);
253
254 return actual_rate;
255}
256
215static void hsb_clk_mode(struct clk *clk, int enabled) 257static void hsb_clk_mode(struct clk *clk, int enabled)
216{ 258{
217 struct at32_sm *sm = &system_manager;
218 unsigned long flags; 259 unsigned long flags;
219 u32 mask; 260 u32 mask;
220 261
221 spin_lock_irqsave(&sm->lock, flags); 262 spin_lock_irqsave(&pm_lock, flags);
222 mask = sm_readl(sm, PM_HSB_MASK); 263 mask = pm_readl(HSB_MASK);
223 if (enabled) 264 if (enabled)
224 mask |= 1 << clk->index; 265 mask |= 1 << clk->index;
225 else 266 else
226 mask &= ~(1 << clk->index); 267 mask &= ~(1 << clk->index);
227 sm_writel(sm, PM_HSB_MASK, mask); 268 pm_writel(HSB_MASK, mask);
228 spin_unlock_irqrestore(&sm->lock, flags); 269 spin_unlock_irqrestore(&pm_lock, flags);
229} 270}
230 271
231static unsigned long hsb_clk_get_rate(struct clk *clk) 272static unsigned long hsb_clk_get_rate(struct clk *clk)
232{ 273{
233 unsigned long cksel, shift = 0; 274 unsigned long cksel, shift = 0;
234 275
235 cksel = sm_readl(&system_manager, PM_CKSEL); 276 cksel = pm_readl(CKSEL);
236 if (cksel & SM_BIT(HSBDIV)) 277 if (cksel & PM_BIT(HSBDIV))
237 shift = SM_BFEXT(HSBSEL, cksel) + 1; 278 shift = PM_BFEXT(HSBSEL, cksel) + 1;
238 279
239 return bus_clk_get_rate(clk, shift); 280 return bus_clk_get_rate(clk, shift);
240} 281}
241 282
242static void pba_clk_mode(struct clk *clk, int enabled) 283static void pba_clk_mode(struct clk *clk, int enabled)
243{ 284{
244 struct at32_sm *sm = &system_manager;
245 unsigned long flags; 285 unsigned long flags;
246 u32 mask; 286 u32 mask;
247 287
248 spin_lock_irqsave(&sm->lock, flags); 288 spin_lock_irqsave(&pm_lock, flags);
249 mask = sm_readl(sm, PM_PBA_MASK); 289 mask = pm_readl(PBA_MASK);
250 if (enabled) 290 if (enabled)
251 mask |= 1 << clk->index; 291 mask |= 1 << clk->index;
252 else 292 else
253 mask &= ~(1 << clk->index); 293 mask &= ~(1 << clk->index);
254 sm_writel(sm, PM_PBA_MASK, mask); 294 pm_writel(PBA_MASK, mask);
255 spin_unlock_irqrestore(&sm->lock, flags); 295 spin_unlock_irqrestore(&pm_lock, flags);
256} 296}
257 297
258static unsigned long pba_clk_get_rate(struct clk *clk) 298static unsigned long pba_clk_get_rate(struct clk *clk)
259{ 299{
260 unsigned long cksel, shift = 0; 300 unsigned long cksel, shift = 0;
261 301
262 cksel = sm_readl(&system_manager, PM_CKSEL); 302 cksel = pm_readl(CKSEL);
263 if (cksel & SM_BIT(PBADIV)) 303 if (cksel & PM_BIT(PBADIV))
264 shift = SM_BFEXT(PBASEL, cksel) + 1; 304 shift = PM_BFEXT(PBASEL, cksel) + 1;
265 305
266 return bus_clk_get_rate(clk, shift); 306 return bus_clk_get_rate(clk, shift);
267} 307}
268 308
269static void pbb_clk_mode(struct clk *clk, int enabled) 309static void pbb_clk_mode(struct clk *clk, int enabled)
270{ 310{
271 struct at32_sm *sm = &system_manager;
272 unsigned long flags; 311 unsigned long flags;
273 u32 mask; 312 u32 mask;
274 313
275 spin_lock_irqsave(&sm->lock, flags); 314 spin_lock_irqsave(&pm_lock, flags);
276 mask = sm_readl(sm, PM_PBB_MASK); 315 mask = pm_readl(PBB_MASK);
277 if (enabled) 316 if (enabled)
278 mask |= 1 << clk->index; 317 mask |= 1 << clk->index;
279 else 318 else
280 mask &= ~(1 << clk->index); 319 mask &= ~(1 << clk->index);
281 sm_writel(sm, PM_PBB_MASK, mask); 320 pm_writel(PBB_MASK, mask);
282 spin_unlock_irqrestore(&sm->lock, flags); 321 spin_unlock_irqrestore(&pm_lock, flags);
283} 322}
284 323
285static unsigned long pbb_clk_get_rate(struct clk *clk) 324static unsigned long pbb_clk_get_rate(struct clk *clk)
286{ 325{
287 unsigned long cksel, shift = 0; 326 unsigned long cksel, shift = 0;
288 327
289 cksel = sm_readl(&system_manager, PM_CKSEL); 328 cksel = pm_readl(CKSEL);
290 if (cksel & SM_BIT(PBBDIV)) 329 if (cksel & PM_BIT(PBBDIV))
291 shift = SM_BFEXT(PBBSEL, cksel) + 1; 330 shift = PM_BFEXT(PBBSEL, cksel) + 1;
292 331
293 return bus_clk_get_rate(clk, shift); 332 return bus_clk_get_rate(clk, shift);
294} 333}
@@ -296,6 +335,7 @@ static unsigned long pbb_clk_get_rate(struct clk *clk)
296static struct clk cpu_clk = { 335static struct clk cpu_clk = {
297 .name = "cpu", 336 .name = "cpu",
298 .get_rate = cpu_clk_get_rate, 337 .get_rate = cpu_clk_get_rate,
338 .set_rate = cpu_clk_set_rate,
299 .users = 1, 339 .users = 1,
300}; 340};
301static struct clk hsb_clk = { 341static struct clk hsb_clk = {
@@ -327,12 +367,12 @@ static void genclk_mode(struct clk *clk, int enabled)
327{ 367{
328 u32 control; 368 u32 control;
329 369
330 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 370 control = pm_readl(GCCTRL(clk->index));
331 if (enabled) 371 if (enabled)
332 control |= SM_BIT(CEN); 372 control |= PM_BIT(CEN);
333 else 373 else
334 control &= ~SM_BIT(CEN); 374 control &= ~PM_BIT(CEN);
335 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control); 375 pm_writel(GCCTRL(clk->index), control);
336} 376}
337 377
338static unsigned long genclk_get_rate(struct clk *clk) 378static unsigned long genclk_get_rate(struct clk *clk)
@@ -340,9 +380,9 @@ static unsigned long genclk_get_rate(struct clk *clk)
340 u32 control; 380 u32 control;
341 unsigned long div = 1; 381 unsigned long div = 1;
342 382
343 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 383 control = pm_readl(GCCTRL(clk->index));
344 if (control & SM_BIT(DIVEN)) 384 if (control & PM_BIT(DIVEN))
345 div = 2 * (SM_BFEXT(DIV, control) + 1); 385 div = 2 * (PM_BFEXT(DIV, control) + 1);
346 386
347 return clk->parent->get_rate(clk->parent) / div; 387 return clk->parent->get_rate(clk->parent) / div;
348} 388}
@@ -353,23 +393,22 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
353 unsigned long parent_rate, actual_rate, div; 393 unsigned long parent_rate, actual_rate, div;
354 394
355 parent_rate = clk->parent->get_rate(clk->parent); 395 parent_rate = clk->parent->get_rate(clk->parent);
356 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 396 control = pm_readl(GCCTRL(clk->index));
357 397
358 if (rate > 3 * parent_rate / 4) { 398 if (rate > 3 * parent_rate / 4) {
359 actual_rate = parent_rate; 399 actual_rate = parent_rate;
360 control &= ~SM_BIT(DIVEN); 400 control &= ~PM_BIT(DIVEN);
361 } else { 401 } else {
362 div = (parent_rate + rate) / (2 * rate) - 1; 402 div = (parent_rate + rate) / (2 * rate) - 1;
363 control = SM_BFINS(DIV, div, control) | SM_BIT(DIVEN); 403 control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN);
364 actual_rate = parent_rate / (2 * (div + 1)); 404 actual_rate = parent_rate / (2 * (div + 1));
365 } 405 }
366 406
367 printk("clk %s: new rate %lu (actual rate %lu)\n", 407 dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n",
368 clk->name, rate, actual_rate); 408 clk->name, rate, actual_rate);
369 409
370 if (apply) 410 if (apply)
371 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, 411 pm_writel(GCCTRL(clk->index), control);
372 control);
373 412
374 return actual_rate; 413 return actual_rate;
375} 414}
@@ -378,24 +417,24 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
378{ 417{
379 u32 control; 418 u32 control;
380 419
381 printk("clk %s: new parent %s (was %s)\n", 420 dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n",
382 clk->name, parent->name, clk->parent->name); 421 clk->name, parent->name, clk->parent->name);
383 422
384 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 423 control = pm_readl(GCCTRL(clk->index));
385 424
386 if (parent == &osc1 || parent == &pll1) 425 if (parent == &osc1 || parent == &pll1)
387 control |= SM_BIT(OSCSEL); 426 control |= PM_BIT(OSCSEL);
388 else if (parent == &osc0 || parent == &pll0) 427 else if (parent == &osc0 || parent == &pll0)
389 control &= ~SM_BIT(OSCSEL); 428 control &= ~PM_BIT(OSCSEL);
390 else 429 else
391 return -EINVAL; 430 return -EINVAL;
392 431
393 if (parent == &pll0 || parent == &pll1) 432 if (parent == &pll0 || parent == &pll1)
394 control |= SM_BIT(PLLSEL); 433 control |= PM_BIT(PLLSEL);
395 else 434 else
396 control &= ~SM_BIT(PLLSEL); 435 control &= ~PM_BIT(PLLSEL);
397 436
398 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control); 437 pm_writel(GCCTRL(clk->index), control);
399 clk->parent = parent; 438 clk->parent = parent;
400 439
401 return 0; 440 return 0;
@@ -408,11 +447,11 @@ static void __init genclk_init_parent(struct clk *clk)
408 447
409 BUG_ON(clk->index > 7); 448 BUG_ON(clk->index > 7);
410 449
411 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index); 450 control = pm_readl(GCCTRL(clk->index));
412 if (control & SM_BIT(OSCSEL)) 451 if (control & PM_BIT(OSCSEL))
413 parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1; 452 parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1;
414 else 453 else
415 parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0; 454 parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0;
416 455
417 clk->parent = parent; 456 clk->parent = parent;
418} 457}
@@ -420,21 +459,53 @@ static void __init genclk_init_parent(struct clk *clk)
420/* -------------------------------------------------------------------- 459/* --------------------------------------------------------------------
421 * System peripherals 460 * System peripherals
422 * -------------------------------------------------------------------- */ 461 * -------------------------------------------------------------------- */
423static struct resource sm_resource[] = { 462static struct resource at32_pm0_resource[] = {
424 PBMEM(0xfff00000), 463 {
425 NAMED_IRQ(19, "eim"), 464 .start = 0xfff00000,
426 NAMED_IRQ(20, "pm"), 465 .end = 0xfff0007f,
427 NAMED_IRQ(21, "rtc"), 466 .flags = IORESOURCE_MEM,
467 },
468 IRQ(20),
428}; 469};
429struct platform_device at32_sm_device = { 470
430 .name = "sm", 471static struct resource at32ap700x_rtc0_resource[] = {
431 .id = 0, 472 {
432 .resource = sm_resource, 473 .start = 0xfff00080,
433 .num_resources = ARRAY_SIZE(sm_resource), 474 .end = 0xfff000af,
475 .flags = IORESOURCE_MEM,
476 },
477 IRQ(21),
478};
479
480static struct resource at32_wdt0_resource[] = {
481 {
482 .start = 0xfff000b0,
483 .end = 0xfff000bf,
484 .flags = IORESOURCE_MEM,
485 },
486};
487
488static struct resource at32_eic0_resource[] = {
489 {
490 .start = 0xfff00100,
491 .end = 0xfff0013f,
492 .flags = IORESOURCE_MEM,
493 },
494 IRQ(19),
434}; 495};
435static struct clk at32_sm_pclk = { 496
497DEFINE_DEV(at32_pm, 0);
498DEFINE_DEV(at32ap700x_rtc, 0);
499DEFINE_DEV(at32_wdt, 0);
500DEFINE_DEV(at32_eic, 0);
501
502/*
503 * Peripheral clock for PM, RTC, WDT and EIC. PM will ensure that this
504 * is always running.
505 */
506static struct clk at32_pm_pclk = {
436 .name = "pclk", 507 .name = "pclk",
437 .dev = &at32_sm_device.dev, 508 .dev = &at32_pm0_device.dev,
438 .parent = &pbb_clk, 509 .parent = &pbb_clk,
439 .mode = pbb_clk_mode, 510 .mode = pbb_clk_mode,
440 .get_rate = pbb_clk_get_rate, 511 .get_rate = pbb_clk_get_rate,
@@ -583,10 +654,11 @@ DEV_CLK(mck, pio4, pba, 14);
583 654
584void __init at32_add_system_devices(void) 655void __init at32_add_system_devices(void)
585{ 656{
586 system_manager.eim_first_irq = EIM_IRQ_BASE; 657 platform_device_register(&at32_pm0_device);
587
588 platform_device_register(&at32_sm_device);
589 platform_device_register(&at32_intc0_device); 658 platform_device_register(&at32_intc0_device);
659 platform_device_register(&at32ap700x_rtc0_device);
660 platform_device_register(&at32_wdt0_device);
661 platform_device_register(&at32_eic0_device);
590 platform_device_register(&smc0_device); 662 platform_device_register(&smc0_device);
591 platform_device_register(&pdc_device); 663 platform_device_register(&pdc_device);
592 664
@@ -1013,6 +1085,89 @@ err_dup_modedb:
1013} 1085}
1014 1086
1015/* -------------------------------------------------------------------- 1087/* --------------------------------------------------------------------
1088 * SSC
1089 * -------------------------------------------------------------------- */
1090static struct resource ssc0_resource[] = {
1091 PBMEM(0xffe01c00),
1092 IRQ(10),
1093};
1094DEFINE_DEV(ssc, 0);
1095DEV_CLK(pclk, ssc0, pba, 7);
1096
1097static struct resource ssc1_resource[] = {
1098 PBMEM(0xffe02000),
1099 IRQ(11),
1100};
1101DEFINE_DEV(ssc, 1);
1102DEV_CLK(pclk, ssc1, pba, 8);
1103
1104static struct resource ssc2_resource[] = {
1105 PBMEM(0xffe02400),
1106 IRQ(12),
1107};
1108DEFINE_DEV(ssc, 2);
1109DEV_CLK(pclk, ssc2, pba, 9);
1110
1111struct platform_device *__init
1112at32_add_device_ssc(unsigned int id, unsigned int flags)
1113{
1114 struct platform_device *pdev;
1115
1116 switch (id) {
1117 case 0:
1118 pdev = &ssc0_device;
1119 if (flags & ATMEL_SSC_RF)
1120 select_peripheral(PA(21), PERIPH_A, 0); /* RF */
1121 if (flags & ATMEL_SSC_RK)
1122 select_peripheral(PA(22), PERIPH_A, 0); /* RK */
1123 if (flags & ATMEL_SSC_TK)
1124 select_peripheral(PA(23), PERIPH_A, 0); /* TK */
1125 if (flags & ATMEL_SSC_TF)
1126 select_peripheral(PA(24), PERIPH_A, 0); /* TF */
1127 if (flags & ATMEL_SSC_TD)
1128 select_peripheral(PA(25), PERIPH_A, 0); /* TD */
1129 if (flags & ATMEL_SSC_RD)
1130 select_peripheral(PA(26), PERIPH_A, 0); /* RD */
1131 break;
1132 case 1:
1133 pdev = &ssc1_device;
1134 if (flags & ATMEL_SSC_RF)
1135 select_peripheral(PA(0), PERIPH_B, 0); /* RF */
1136 if (flags & ATMEL_SSC_RK)
1137 select_peripheral(PA(1), PERIPH_B, 0); /* RK */
1138 if (flags & ATMEL_SSC_TK)
1139 select_peripheral(PA(2), PERIPH_B, 0); /* TK */
1140 if (flags & ATMEL_SSC_TF)
1141 select_peripheral(PA(3), PERIPH_B, 0); /* TF */
1142 if (flags & ATMEL_SSC_TD)
1143 select_peripheral(PA(4), PERIPH_B, 0); /* TD */
1144 if (flags & ATMEL_SSC_RD)
1145 select_peripheral(PA(5), PERIPH_B, 0); /* RD */
1146 break;
1147 case 2:
1148 pdev = &ssc2_device;
1149 if (flags & ATMEL_SSC_TD)
1150 select_peripheral(PB(13), PERIPH_A, 0); /* TD */
1151 if (flags & ATMEL_SSC_RD)
1152 select_peripheral(PB(14), PERIPH_A, 0); /* RD */
1153 if (flags & ATMEL_SSC_TK)
1154 select_peripheral(PB(15), PERIPH_A, 0); /* TK */
1155 if (flags & ATMEL_SSC_TF)
1156 select_peripheral(PB(16), PERIPH_A, 0); /* TF */
1157 if (flags & ATMEL_SSC_RF)
1158 select_peripheral(PB(17), PERIPH_A, 0); /* RF */
1159 if (flags & ATMEL_SSC_RK)
1160 select_peripheral(PB(18), PERIPH_A, 0); /* RK */
1161 break;
1162 default:
1163 return NULL;
1164 }
1165
1166 platform_device_register(pdev);
1167 return pdev;
1168}
1169
1170/* --------------------------------------------------------------------
1016 * GCLK 1171 * GCLK
1017 * -------------------------------------------------------------------- */ 1172 * -------------------------------------------------------------------- */
1018static struct clk gclk0 = { 1173static struct clk gclk0 = {
@@ -1066,7 +1221,7 @@ struct clk *at32_clock_list[] = {
1066 &hsb_clk, 1221 &hsb_clk,
1067 &pba_clk, 1222 &pba_clk,
1068 &pbb_clk, 1223 &pbb_clk,
1069 &at32_sm_pclk, 1224 &at32_pm_pclk,
1070 &at32_intc0_pclk, 1225 &at32_intc0_pclk,
1071 &hmatrix_clk, 1226 &hmatrix_clk,
1072 &ebi_clk, 1227 &ebi_clk,
@@ -1094,6 +1249,9 @@ struct clk *at32_clock_list[] = {
1094 &atmel_spi1_spi_clk, 1249 &atmel_spi1_spi_clk,
1095 &atmel_lcdfb0_hck1, 1250 &atmel_lcdfb0_hck1,
1096 &atmel_lcdfb0_pixclk, 1251 &atmel_lcdfb0_pixclk,
1252 &ssc0_pclk,
1253 &ssc1_pclk,
1254 &ssc2_pclk,
1097 &gclk0, 1255 &gclk0,
1098 &gclk1, 1256 &gclk1,
1099 &gclk2, 1257 &gclk2,
@@ -1113,18 +1271,20 @@ void __init at32_portmux_init(void)
1113 1271
1114void __init at32_clock_init(void) 1272void __init at32_clock_init(void)
1115{ 1273{
1116 struct at32_sm *sm = &system_manager;
1117 u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0; 1274 u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
1118 int i; 1275 int i;
1119 1276
1120 if (sm_readl(sm, PM_MCCTRL) & SM_BIT(PLLSEL)) 1277 if (pm_readl(MCCTRL) & PM_BIT(PLLSEL)) {
1121 main_clock = &pll0; 1278 main_clock = &pll0;
1122 else 1279 cpu_clk.parent = &pll0;
1280 } else {
1123 main_clock = &osc0; 1281 main_clock = &osc0;
1282 cpu_clk.parent = &osc0;
1283 }
1124 1284
1125 if (sm_readl(sm, PM_PLL0) & SM_BIT(PLLOSC)) 1285 if (pm_readl(PLL0) & PM_BIT(PLLOSC))
1126 pll0.parent = &osc1; 1286 pll0.parent = &osc1;
1127 if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC)) 1287 if (pm_readl(PLL1) & PM_BIT(PLLOSC))
1128 pll1.parent = &osc1; 1288 pll1.parent = &osc1;
1129 1289
1130 genclk_init_parent(&gclk0); 1290 genclk_init_parent(&gclk0);
@@ -1157,8 +1317,8 @@ void __init at32_clock_init(void)
1157 pbb_mask |= 1 << clk->index; 1317 pbb_mask |= 1 << clk->index;
1158 } 1318 }
1159 1319
1160 sm_writel(sm, PM_CPU_MASK, cpu_mask); 1320 pm_writel(CPU_MASK, cpu_mask);
1161 sm_writel(sm, PM_HSB_MASK, hsb_mask); 1321 pm_writel(HSB_MASK, hsb_mask);
1162 sm_writel(sm, PM_PBA_MASK, pba_mask); 1322 pm_writel(PBA_MASK, pba_mask);
1163 sm_writel(sm, PM_PBB_MASK, pbb_mask); 1323 pm_writel(PBB_MASK, pbb_mask);
1164} 1324}
diff --git a/arch/avr32/mach-at32ap/cpufreq.c b/arch/avr32/mach-at32ap/cpufreq.c
new file mode 100644
index 00000000000..235524b7919
--- /dev/null
+++ b/arch/avr32/mach-at32ap/cpufreq.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright (C) 2004-2007 Atmel Corporation
3 *
4 * Based on MIPS implementation arch/mips/kernel/time.c
5 * Copyright 2001 MontaVista Software Inc.
6 *
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
9 * published by the Free Software Foundation.
10 */
11
12/*#define DEBUG*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/init.h>
17#include <linux/cpufreq.h>
18#include <linux/io.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <asm/system.h>
22
23static struct clk *cpuclk;
24
25static int at32_verify_speed(struct cpufreq_policy *policy)
26{
27 if (policy->cpu != 0)
28 return -EINVAL;
29
30 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
31 policy->cpuinfo.max_freq);
32 return 0;
33}
34
35static unsigned int at32_get_speed(unsigned int cpu)
36{
37 /* No SMP support */
38 if (cpu)
39 return 0;
40 return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000);
41}
42
43static int at32_set_target(struct cpufreq_policy *policy,
44 unsigned int target_freq,
45 unsigned int relation)
46{
47 struct cpufreq_freqs freqs;
48 long freq;
49
50 /* Convert target_freq from kHz to Hz */
51 freq = clk_round_rate(cpuclk, target_freq * 1000);
52
53 /* Check if policy->min <= new_freq <= policy->max */
54 if(freq < (policy->min * 1000) || freq > (policy->max * 1000))
55 return -EINVAL;
56
57 pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
58
59 freqs.old = at32_get_speed(0);
60 freqs.new = (freq + 500) / 1000;
61 freqs.cpu = 0;
62 freqs.flags = 0;
63
64 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
65 clk_set_rate(cpuclk, freq);
66 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
67
68 pr_debug("cpufreq: set frequency %lu Hz\n", freq);
69
70 return 0;
71}
72
73static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
74{
75 if (policy->cpu != 0)
76 return -EINVAL;
77
78 cpuclk = clk_get(NULL, "cpu");
79 if (IS_ERR(cpuclk)) {
80 pr_debug("cpufreq: could not get CPU clk\n");
81 return PTR_ERR(cpuclk);
82 }
83
84 policy->cpuinfo.min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000;
85 policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000;
86 policy->cpuinfo.transition_latency = 0;
87 policy->cur = at32_get_speed(0);
88 policy->min = policy->cpuinfo.min_freq;
89 policy->max = policy->cpuinfo.max_freq;
90 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
91
92 printk("cpufreq: AT32AP CPU frequency driver\n");
93
94 return 0;
95}
96
97static struct cpufreq_driver at32_driver = {
98 .name = "at32ap",
99 .owner = THIS_MODULE,
100 .init = at32_cpufreq_driver_init,
101 .verify = at32_verify_speed,
102 .target = at32_set_target,
103 .get = at32_get_speed,
104 .flags = CPUFREQ_STICKY,
105};
106
107static int __init at32_cpufreq_init(void)
108{
109 return cpufreq_register_driver(&at32_driver);
110}
111
112arch_initcall(at32_cpufreq_init);
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 4a60eccfebd..8acd0109003 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -17,42 +17,83 @@
17 17
18#include <asm/io.h> 18#include <asm/io.h>
19 19
20#include <asm/arch/sm.h> 20/* EIC register offsets */
21 21#define EIC_IER 0x0000
22#include "sm.h" 22#define EIC_IDR 0x0004
23#define EIC_IMR 0x0008
24#define EIC_ISR 0x000c
25#define EIC_ICR 0x0010
26#define EIC_MODE 0x0014
27#define EIC_EDGE 0x0018
28#define EIC_LEVEL 0x001c
29#define EIC_TEST 0x0020
30#define EIC_NMIC 0x0024
31
32/* Bitfields in TEST */
33#define EIC_TESTEN_OFFSET 31
34#define EIC_TESTEN_SIZE 1
35
36/* Bitfields in NMIC */
37#define EIC_EN_OFFSET 0
38#define EIC_EN_SIZE 1
39
40/* Bit manipulation macros */
41#define EIC_BIT(name) \
42 (1 << EIC_##name##_OFFSET)
43#define EIC_BF(name,value) \
44 (((value) & ((1 << EIC_##name##_SIZE) - 1)) \
45 << EIC_##name##_OFFSET)
46#define EIC_BFEXT(name,value) \
47 (((value) >> EIC_##name##_OFFSET) \
48 & ((1 << EIC_##name##_SIZE) - 1))
49#define EIC_BFINS(name,value,old) \
50 (((old) & ~(((1 << EIC_##name##_SIZE) - 1) \
51 << EIC_##name##_OFFSET)) \
52 | EIC_BF(name,value))
53
54/* Register access macros */
55#define eic_readl(port,reg) \
56 __raw_readl((port)->regs + EIC_##reg)
57#define eic_writel(port,reg,value) \
58 __raw_writel((value), (port)->regs + EIC_##reg)
59
60struct eic {
61 void __iomem *regs;
62 struct irq_chip *chip;
63 unsigned int first_irq;
64};
23 65
24static void eim_ack_irq(unsigned int irq) 66static void eic_ack_irq(unsigned int irq)
25{ 67{
26 struct at32_sm *sm = get_irq_chip_data(irq); 68 struct eic *eic = get_irq_chip_data(irq);
27 sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq)); 69 eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
28} 70}
29 71
30static void eim_mask_irq(unsigned int irq) 72static void eic_mask_irq(unsigned int irq)
31{ 73{
32 struct at32_sm *sm = get_irq_chip_data(irq); 74 struct eic *eic = get_irq_chip_data(irq);
33 sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq)); 75 eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
34} 76}
35 77
36static void eim_mask_ack_irq(unsigned int irq) 78static void eic_mask_ack_irq(unsigned int irq)
37{ 79{
38 struct at32_sm *sm = get_irq_chip_data(irq); 80 struct eic *eic = get_irq_chip_data(irq);
39 sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq)); 81 eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
40 sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq)); 82 eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
41} 83}
42 84
43static void eim_unmask_irq(unsigned int irq) 85static void eic_unmask_irq(unsigned int irq)
44{ 86{
45 struct at32_sm *sm = get_irq_chip_data(irq); 87 struct eic *eic = get_irq_chip_data(irq);
46 sm_writel(sm, EIM_IER, 1 << (irq - sm->eim_first_irq)); 88 eic_writel(eic, IER, 1 << (irq - eic->first_irq));
47} 89}
48 90
49static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) 91static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
50{ 92{
51 struct at32_sm *sm = get_irq_chip_data(irq); 93 struct eic *eic = get_irq_chip_data(irq);
52 struct irq_desc *desc; 94 struct irq_desc *desc;
53 unsigned int i = irq - sm->eim_first_irq; 95 unsigned int i = irq - eic->first_irq;
54 u32 mode, edge, level; 96 u32 mode, edge, level;
55 unsigned long flags;
56 int ret = 0; 97 int ret = 0;
57 98
58 flow_type &= IRQ_TYPE_SENSE_MASK; 99 flow_type &= IRQ_TYPE_SENSE_MASK;
@@ -60,11 +101,10 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
60 flow_type = IRQ_TYPE_LEVEL_LOW; 101 flow_type = IRQ_TYPE_LEVEL_LOW;
61 102
62 desc = &irq_desc[irq]; 103 desc = &irq_desc[irq];
63 spin_lock_irqsave(&sm->lock, flags);
64 104
65 mode = sm_readl(sm, EIM_MODE); 105 mode = eic_readl(eic, MODE);
66 edge = sm_readl(sm, EIM_EDGE); 106 edge = eic_readl(eic, EDGE);
67 level = sm_readl(sm, EIM_LEVEL); 107 level = eic_readl(eic, LEVEL);
68 108
69 switch (flow_type) { 109 switch (flow_type) {
70 case IRQ_TYPE_LEVEL_LOW: 110 case IRQ_TYPE_LEVEL_LOW:
@@ -89,9 +129,9 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
89 } 129 }
90 130
91 if (ret == 0) { 131 if (ret == 0) {
92 sm_writel(sm, EIM_MODE, mode); 132 eic_writel(eic, MODE, mode);
93 sm_writel(sm, EIM_EDGE, edge); 133 eic_writel(eic, EDGE, edge);
94 sm_writel(sm, EIM_LEVEL, level); 134 eic_writel(eic, LEVEL, level);
95 135
96 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 136 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
97 flow_type |= IRQ_LEVEL; 137 flow_type |= IRQ_LEVEL;
@@ -99,35 +139,33 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
99 desc->status |= flow_type; 139 desc->status |= flow_type;
100 } 140 }
101 141
102 spin_unlock_irqrestore(&sm->lock, flags);
103
104 return ret; 142 return ret;
105} 143}
106 144
107struct irq_chip eim_chip = { 145struct irq_chip eic_chip = {
108 .name = "eim", 146 .name = "eic",
109 .ack = eim_ack_irq, 147 .ack = eic_ack_irq,
110 .mask = eim_mask_irq, 148 .mask = eic_mask_irq,
111 .mask_ack = eim_mask_ack_irq, 149 .mask_ack = eic_mask_ack_irq,
112 .unmask = eim_unmask_irq, 150 .unmask = eic_unmask_irq,
113 .set_type = eim_set_irq_type, 151 .set_type = eic_set_irq_type,
114}; 152};
115 153
116static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) 154static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
117{ 155{
118 struct at32_sm *sm = desc->handler_data; 156 struct eic *eic = desc->handler_data;
119 struct irq_desc *ext_desc; 157 struct irq_desc *ext_desc;
120 unsigned long status, pending; 158 unsigned long status, pending;
121 unsigned int i, ext_irq; 159 unsigned int i, ext_irq;
122 160
123 status = sm_readl(sm, EIM_ISR); 161 status = eic_readl(eic, ISR);
124 pending = status & sm_readl(sm, EIM_IMR); 162 pending = status & eic_readl(eic, IMR);
125 163
126 while (pending) { 164 while (pending) {
127 i = fls(pending) - 1; 165 i = fls(pending) - 1;
128 pending &= ~(1 << i); 166 pending &= ~(1 << i);
129 167
130 ext_irq = i + sm->eim_first_irq; 168 ext_irq = i + eic->first_irq;
131 ext_desc = irq_desc + ext_irq; 169 ext_desc = irq_desc + ext_irq;
132 if (ext_desc->status & IRQ_LEVEL) 170 if (ext_desc->status & IRQ_LEVEL)
133 handle_level_irq(ext_irq, ext_desc); 171 handle_level_irq(ext_irq, ext_desc);
@@ -136,51 +174,85 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
136 } 174 }
137} 175}
138 176
139static int __init eim_init(void) 177static int __init eic_probe(struct platform_device *pdev)
140{ 178{
141 struct at32_sm *sm = &system_manager; 179 struct eic *eic;
180 struct resource *regs;
142 unsigned int i; 181 unsigned int i;
143 unsigned int nr_irqs; 182 unsigned int nr_irqs;
144 unsigned int int_irq; 183 unsigned int int_irq;
184 int ret;
145 u32 pattern; 185 u32 pattern;
146 186
147 /* 187 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
148 * The EIM is really the same module as SM, so register 188 int_irq = platform_get_irq(pdev, 0);
149 * mapping, etc. has been taken care of already. 189 if (!regs || !int_irq) {
150 */ 190 dev_dbg(&pdev->dev, "missing regs and/or irq resource\n");
191 return -ENXIO;
192 }
193
194 ret = -ENOMEM;
195 eic = kzalloc(sizeof(struct eic), GFP_KERNEL);
196 if (!eic) {
197 dev_dbg(&pdev->dev, "no memory for eic structure\n");
198 goto err_kzalloc;
199 }
200
201 eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id;
202 eic->regs = ioremap(regs->start, regs->end - regs->start + 1);
203 if (!eic->regs) {
204 dev_dbg(&pdev->dev, "failed to map regs\n");
205 goto err_ioremap;
206 }
151 207
152 /* 208 /*
153 * Find out how many interrupt lines that are actually 209 * Find out how many interrupt lines that are actually
154 * implemented in hardware. 210 * implemented in hardware.
155 */ 211 */
156 sm_writel(sm, EIM_IDR, ~0UL); 212 eic_writel(eic, IDR, ~0UL);
157 sm_writel(sm, EIM_MODE, ~0UL); 213 eic_writel(eic, MODE, ~0UL);
158 pattern = sm_readl(sm, EIM_MODE); 214 pattern = eic_readl(eic, MODE);
159 nr_irqs = fls(pattern); 215 nr_irqs = fls(pattern);
160 216
161 /* Trigger on falling edge unless overridden by driver */ 217 /* Trigger on falling edge unless overridden by driver */
162 sm_writel(sm, EIM_MODE, 0UL); 218 eic_writel(eic, MODE, 0UL);
163 sm_writel(sm, EIM_EDGE, 0UL); 219 eic_writel(eic, EDGE, 0UL);
164 220
165 sm->eim_chip = &eim_chip; 221 eic->chip = &eic_chip;
166 222
167 for (i = 0; i < nr_irqs; i++) { 223 for (i = 0; i < nr_irqs; i++) {
168 /* NOTE the handler we set here is ignored by the demux */ 224 /* NOTE the handler we set here is ignored by the demux */
169 set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, 225 set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
170 handle_level_irq); 226 handle_level_irq);
171 set_irq_chip_data(sm->eim_first_irq + i, sm); 227 set_irq_chip_data(eic->first_irq + i, eic);
172 } 228 }
173 229
174 int_irq = platform_get_irq_byname(sm->pdev, "eim"); 230 set_irq_chained_handler(int_irq, demux_eic_irq);
175 231 set_irq_data(int_irq, eic);
176 set_irq_chained_handler(int_irq, demux_eim_irq);
177 set_irq_data(int_irq, sm);
178 232
179 printk("EIM: External Interrupt Module at 0x%p, IRQ %u\n", 233 dev_info(&pdev->dev,
180 sm->regs, int_irq); 234 "External Interrupt Controller at 0x%p, IRQ %u\n",
181 printk("EIM: Handling %u external IRQs, starting with IRQ %u\n", 235 eic->regs, int_irq);
182 nr_irqs, sm->eim_first_irq); 236 dev_info(&pdev->dev,
237 "Handling %u external IRQs, starting with IRQ %u\n",
238 nr_irqs, eic->first_irq);
183 239
184 return 0; 240 return 0;
241
242err_ioremap:
243 kfree(eic);
244err_kzalloc:
245 return ret;
246}
247
248static struct platform_driver eic_driver = {
249 .driver = {
250 .name = "at32_eic",
251 },
252};
253
254static int __init eic_init(void)
255{
256 return platform_driver_probe(&eic_driver, eic_probe);
185} 257}
186arch_initcall(eim_init); 258arch_initcall(eic_init);
diff --git a/arch/avr32/mach-at32ap/pm.h b/arch/avr32/mach-at32ap/pm.h
new file mode 100644
index 00000000000..a1f8aced0a8
--- /dev/null
+++ b/arch/avr32/mach-at32ap/pm.h
@@ -0,0 +1,112 @@
1/*
2 * Register definitions for the Power Manager (PM)
3 */
4#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
5#define __ARCH_AVR32_MACH_AT32AP_PM_H__
6
7/* PM register offsets */
8#define PM_MCCTRL 0x0000
9#define PM_CKSEL 0x0004
10#define PM_CPU_MASK 0x0008
11#define PM_HSB_MASK 0x000c
12#define PM_PBA_MASK 0x0010
13#define PM_PBB_MASK 0x0014
14#define PM_PLL0 0x0020
15#define PM_PLL1 0x0024
16#define PM_IER 0x0040
17#define PM_IDR 0x0044
18#define PM_IMR 0x0048
19#define PM_ISR 0x004c
20#define PM_ICR 0x0050
21#define PM_GCCTRL(x) (0x0060 + 4 * (x))
22#define PM_RCAUSE 0x00c0
23
24/* Bitfields in CKSEL */
25#define PM_CPUSEL_OFFSET 0
26#define PM_CPUSEL_SIZE 3
27#define PM_CPUDIV_OFFSET 7
28#define PM_CPUDIV_SIZE 1
29#define PM_HSBSEL_OFFSET 8
30#define PM_HSBSEL_SIZE 3
31#define PM_HSBDIV_OFFSET 15
32#define PM_HSBDIV_SIZE 1
33#define PM_PBASEL_OFFSET 16
34#define PM_PBASEL_SIZE 3
35#define PM_PBADIV_OFFSET 23
36#define PM_PBADIV_SIZE 1
37#define PM_PBBSEL_OFFSET 24
38#define PM_PBBSEL_SIZE 3
39#define PM_PBBDIV_OFFSET 31
40#define PM_PBBDIV_SIZE 1
41
42/* Bitfields in PLL0 */
43#define PM_PLLEN_OFFSET 0
44#define PM_PLLEN_SIZE 1
45#define PM_PLLOSC_OFFSET 1
46#define PM_PLLOSC_SIZE 1
47#define PM_PLLOPT_OFFSET 2
48#define PM_PLLOPT_SIZE 3
49#define PM_PLLDIV_OFFSET 8
50#define PM_PLLDIV_SIZE 8
51#define PM_PLLMUL_OFFSET 16
52#define PM_PLLMUL_SIZE 8
53#define PM_PLLCOUNT_OFFSET 24
54#define PM_PLLCOUNT_SIZE 6
55#define PM_PLLTEST_OFFSET 31
56#define PM_PLLTEST_SIZE 1
57
58/* Bitfields in ICR */
59#define PM_LOCK0_OFFSET 0
60#define PM_LOCK0_SIZE 1
61#define PM_LOCK1_OFFSET 1
62#define PM_LOCK1_SIZE 1
63#define PM_WAKE_OFFSET 2
64#define PM_WAKE_SIZE 1
65#define PM_CKRDY_OFFSET 5
66#define PM_CKRDY_SIZE 1
67#define PM_MSKRDY_OFFSET 6
68#define PM_MSKRDY_SIZE 1
69
70/* Bitfields in GCCTRL0 */
71#define PM_OSCSEL_OFFSET 0
72#define PM_OSCSEL_SIZE 1
73#define PM_PLLSEL_OFFSET 1
74#define PM_PLLSEL_SIZE 1
75#define PM_CEN_OFFSET 2
76#define PM_CEN_SIZE 1
77#define PM_DIVEN_OFFSET 4
78#define PM_DIVEN_SIZE 1
79#define PM_DIV_OFFSET 8
80#define PM_DIV_SIZE 8
81
82/* Bitfields in RCAUSE */
83#define PM_POR_OFFSET 0
84#define PM_POR_SIZE 1
85#define PM_EXT_OFFSET 2
86#define PM_EXT_SIZE 1
87#define PM_WDT_OFFSET 3
88#define PM_WDT_SIZE 1
89#define PM_NTAE_OFFSET 4
90#define PM_NTAE_SIZE 1
91
92/* Bit manipulation macros */
93#define PM_BIT(name) \
94 (1 << PM_##name##_OFFSET)
95#define PM_BF(name,value) \
96 (((value) & ((1 << PM_##name##_SIZE) - 1)) \
97 << PM_##name##_OFFSET)
98#define PM_BFEXT(name,value) \
99 (((value) >> PM_##name##_OFFSET) \
100 & ((1 << PM_##name##_SIZE) - 1))
101#define PM_BFINS(name,value,old)\
102 (((old) & ~(((1 << PM_##name##_SIZE) - 1) \
103 << PM_##name##_OFFSET)) \
104 | PM_BF(name,value))
105
106/* Register access macros */
107#define pm_readl(reg) \
108 __raw_readl((void __iomem *)AT32_PM_BASE + PM_##reg)
109#define pm_writel(reg,value) \
110 __raw_writel((value), (void __iomem *)AT32_PM_BASE + PM_##reg)
111
112#endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
diff --git a/arch/avr32/mach-at32ap/sm.h b/arch/avr32/mach-at32ap/sm.h
deleted file mode 100644
index cad02b512bc..00000000000
--- a/arch/avr32/mach-at32ap/sm.h
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * Register definitions for SM
3 *
4 * System Manager
5 */
6#ifndef __ASM_AVR32_SM_H__
7#define __ASM_AVR32_SM_H__
8
9/* SM register offsets */
10#define SM_PM_MCCTRL 0x0000
11#define SM_PM_CKSEL 0x0004
12#define SM_PM_CPU_MASK 0x0008
13#define SM_PM_HSB_MASK 0x000c
14#define SM_PM_PBA_MASK 0x0010
15#define SM_PM_PBB_MASK 0x0014
16#define SM_PM_PLL0 0x0020
17#define SM_PM_PLL1 0x0024
18#define SM_PM_VCTRL 0x0030
19#define SM_PM_VMREF 0x0034
20#define SM_PM_VMV 0x0038
21#define SM_PM_IER 0x0040
22#define SM_PM_IDR 0x0044
23#define SM_PM_IMR 0x0048
24#define SM_PM_ISR 0x004c
25#define SM_PM_ICR 0x0050
26#define SM_PM_GCCTRL 0x0060
27#define SM_RTC_CTRL 0x0080
28#define SM_RTC_VAL 0x0084
29#define SM_RTC_TOP 0x0088
30#define SM_RTC_IER 0x0090
31#define SM_RTC_IDR 0x0094
32#define SM_RTC_IMR 0x0098
33#define SM_RTC_ISR 0x009c
34#define SM_RTC_ICR 0x00a0
35#define SM_WDT_CTRL 0x00b0
36#define SM_WDT_CLR 0x00b4
37#define SM_WDT_EXT 0x00b8
38#define SM_RC_RCAUSE 0x00c0
39#define SM_EIM_IER 0x0100
40#define SM_EIM_IDR 0x0104
41#define SM_EIM_IMR 0x0108
42#define SM_EIM_ISR 0x010c
43#define SM_EIM_ICR 0x0110
44#define SM_EIM_MODE 0x0114
45#define SM_EIM_EDGE 0x0118
46#define SM_EIM_LEVEL 0x011c
47#define SM_EIM_TEST 0x0120
48#define SM_EIM_NMIC 0x0124
49
50/* Bitfields in PM_MCCTRL */
51
52/* Bitfields in PM_CKSEL */
53#define SM_CPUSEL_OFFSET 0
54#define SM_CPUSEL_SIZE 3
55#define SM_CPUDIV_OFFSET 7
56#define SM_CPUDIV_SIZE 1
57#define SM_HSBSEL_OFFSET 8
58#define SM_HSBSEL_SIZE 3
59#define SM_HSBDIV_OFFSET 15
60#define SM_HSBDIV_SIZE 1
61#define SM_PBASEL_OFFSET 16
62#define SM_PBASEL_SIZE 3
63#define SM_PBADIV_OFFSET 23
64#define SM_PBADIV_SIZE 1
65#define SM_PBBSEL_OFFSET 24
66#define SM_PBBSEL_SIZE 3
67#define SM_PBBDIV_OFFSET 31
68#define SM_PBBDIV_SIZE 1
69
70/* Bitfields in PM_CPU_MASK */
71
72/* Bitfields in PM_HSB_MASK */
73
74/* Bitfields in PM_PBA_MASK */
75
76/* Bitfields in PM_PBB_MASK */
77
78/* Bitfields in PM_PLL0 */
79#define SM_PLLEN_OFFSET 0
80#define SM_PLLEN_SIZE 1
81#define SM_PLLOSC_OFFSET 1
82#define SM_PLLOSC_SIZE 1
83#define SM_PLLOPT_OFFSET 2
84#define SM_PLLOPT_SIZE 3
85#define SM_PLLDIV_OFFSET 8
86#define SM_PLLDIV_SIZE 8
87#define SM_PLLMUL_OFFSET 16
88#define SM_PLLMUL_SIZE 8
89#define SM_PLLCOUNT_OFFSET 24
90#define SM_PLLCOUNT_SIZE 6
91#define SM_PLLTEST_OFFSET 31
92#define SM_PLLTEST_SIZE 1
93
94/* Bitfields in PM_PLL1 */
95
96/* Bitfields in PM_VCTRL */
97#define SM_VAUTO_OFFSET 0
98#define SM_VAUTO_SIZE 1
99#define SM_PM_VCTRL_VAL_OFFSET 8
100#define SM_PM_VCTRL_VAL_SIZE 7
101
102/* Bitfields in PM_VMREF */
103#define SM_REFSEL_OFFSET 0
104#define SM_REFSEL_SIZE 4
105
106/* Bitfields in PM_VMV */
107#define SM_PM_VMV_VAL_OFFSET 0
108#define SM_PM_VMV_VAL_SIZE 8
109
110/* Bitfields in PM_IER */
111
112/* Bitfields in PM_IDR */
113
114/* Bitfields in PM_IMR */
115
116/* Bitfields in PM_ISR */
117
118/* Bitfields in PM_ICR */
119#define SM_LOCK0_OFFSET 0
120#define SM_LOCK0_SIZE 1
121#define SM_LOCK1_OFFSET 1
122#define SM_LOCK1_SIZE 1
123#define SM_WAKE_OFFSET 2
124#define SM_WAKE_SIZE 1
125#define SM_VOK_OFFSET 3
126#define SM_VOK_SIZE 1
127#define SM_VMRDY_OFFSET 4
128#define SM_VMRDY_SIZE 1
129#define SM_CKRDY_OFFSET 5
130#define SM_CKRDY_SIZE 1
131
132/* Bitfields in PM_GCCTRL */
133#define SM_OSCSEL_OFFSET 0
134#define SM_OSCSEL_SIZE 1
135#define SM_PLLSEL_OFFSET 1
136#define SM_PLLSEL_SIZE 1
137#define SM_CEN_OFFSET 2
138#define SM_CEN_SIZE 1
139#define SM_CPC_OFFSET 3
140#define SM_CPC_SIZE 1
141#define SM_DIVEN_OFFSET 4
142#define SM_DIVEN_SIZE 1
143#define SM_DIV_OFFSET 8
144#define SM_DIV_SIZE 8
145
146/* Bitfields in RTC_CTRL */
147#define SM_PCLR_OFFSET 1
148#define SM_PCLR_SIZE 1
149#define SM_TOPEN_OFFSET 2
150#define SM_TOPEN_SIZE 1
151#define SM_CLKEN_OFFSET 3
152#define SM_CLKEN_SIZE 1
153#define SM_PSEL_OFFSET 8
154#define SM_PSEL_SIZE 16
155
156/* Bitfields in RTC_VAL */
157#define SM_RTC_VAL_VAL_OFFSET 0
158#define SM_RTC_VAL_VAL_SIZE 31
159
160/* Bitfields in RTC_TOP */
161#define SM_RTC_TOP_VAL_OFFSET 0
162#define SM_RTC_TOP_VAL_SIZE 32
163
164/* Bitfields in RTC_IER */
165
166/* Bitfields in RTC_IDR */
167
168/* Bitfields in RTC_IMR */
169
170/* Bitfields in RTC_ISR */
171
172/* Bitfields in RTC_ICR */
173#define SM_TOPI_OFFSET 0
174#define SM_TOPI_SIZE 1
175
176/* Bitfields in WDT_CTRL */
177#define SM_KEY_OFFSET 24
178#define SM_KEY_SIZE 8
179
180/* Bitfields in WDT_CLR */
181
182/* Bitfields in WDT_EXT */
183
184/* Bitfields in RC_RCAUSE */
185#define SM_POR_OFFSET 0
186#define SM_POR_SIZE 1
187#define SM_BOD_OFFSET 1
188#define SM_BOD_SIZE 1
189#define SM_EXT_OFFSET 2
190#define SM_EXT_SIZE 1
191#define SM_WDT_OFFSET 3
192#define SM_WDT_SIZE 1
193#define SM_NTAE_OFFSET 4
194#define SM_NTAE_SIZE 1
195#define SM_SERP_OFFSET 5
196#define SM_SERP_SIZE 1
197
198/* Bitfields in EIM_IER */
199
200/* Bitfields in EIM_IDR */
201
202/* Bitfields in EIM_IMR */
203
204/* Bitfields in EIM_ISR */
205
206/* Bitfields in EIM_ICR */
207
208/* Bitfields in EIM_MODE */
209
210/* Bitfields in EIM_EDGE */
211#define SM_INT0_OFFSET 0
212#define SM_INT0_SIZE 1
213#define SM_INT1_OFFSET 1
214#define SM_INT1_SIZE 1
215#define SM_INT2_OFFSET 2
216#define SM_INT2_SIZE 1
217#define SM_INT3_OFFSET 3
218#define SM_INT3_SIZE 1
219
220/* Bitfields in EIM_LEVEL */
221
222/* Bitfields in EIM_TEST */
223#define SM_TESTEN_OFFSET 31
224#define SM_TESTEN_SIZE 1
225
226/* Bitfields in EIM_NMIC */
227#define SM_EN_OFFSET 0
228#define SM_EN_SIZE 1
229
230/* Bit manipulation macros */
231#define SM_BIT(name) (1 << SM_##name##_OFFSET)
232#define SM_BF(name,value) (((value) & ((1 << SM_##name##_SIZE) - 1)) << SM_##name##_OFFSET)
233#define SM_BFEXT(name,value) (((value) >> SM_##name##_OFFSET) & ((1 << SM_##name##_SIZE) - 1))
234#define SM_BFINS(name,value,old) (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
235
236/* Register access macros */
237#define sm_readl(port,reg) \
238 __raw_readl((port)->regs + SM_##reg)
239#define sm_writel(port,reg,value) \
240 __raw_writel((value), (port)->regs + SM_##reg)
241
242#endif /* __ASM_AVR32_SM_H__ */
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h
index 97448043884..0215965dc58 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -36,4 +36,18 @@ struct platform_device *
36at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, 36at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
37 unsigned long fbmem_start, unsigned long fbmem_len); 37 unsigned long fbmem_start, unsigned long fbmem_len);
38 38
39/* depending on what's hooked up, not all SSC pins will be used */
40#define ATMEL_SSC_TK 0x01
41#define ATMEL_SSC_TF 0x02
42#define ATMEL_SSC_TD 0x04
43#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD)
44
45#define ATMEL_SSC_RK 0x10
46#define ATMEL_SSC_RF 0x20
47#define ATMEL_SSC_RD 0x40
48#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD)
49
50struct platform_device *
51at32_add_device_ssc(unsigned int id, unsigned int flags);
52
39#endif /* __ASM_ARCH_BOARD_H */ 53#endif /* __ASM_ARCH_BOARD_H */
diff --git a/include/asm-avr32/arch-at32ap/sm.h b/include/asm-avr32/arch-at32ap/sm.h
deleted file mode 100644
index 265a9ead20b..00000000000
--- a/include/asm-avr32/arch-at32ap/sm.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * AT32 System Manager interface.
3 *
4 * Copyright (C) 2006 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 __ASM_AVR32_AT32_SM_H__
11#define __ASM_AVR32_AT32_SM_H__
12
13struct irq_chip;
14struct platform_device;
15
16struct at32_sm {
17 spinlock_t lock;
18 void __iomem *regs;
19 struct irq_chip *eim_chip;
20 unsigned int eim_first_irq;
21 struct platform_device *pdev;
22};
23
24extern struct platform_device at32_sm_device;
25extern struct at32_sm system_manager;
26
27#endif /* __ASM_AVR32_AT32_SM_H__ */
diff --git a/include/asm-avr32/atomic.h b/include/asm-avr32/atomic.h
index b9c2548a52f..7ef3862a73d 100644
--- a/include/asm-avr32/atomic.h
+++ b/include/asm-avr32/atomic.h
@@ -101,7 +101,7 @@ static inline int atomic_sub_unless(atomic_t *v, int a, int u)
101 " mov %1, 1\n" 101 " mov %1, 1\n"
102 "1:" 102 "1:"
103 : "=&r"(tmp), "=&r"(result), "=o"(v->counter) 103 : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
104 : "m"(v->counter), "rKs21"(a), "rKs21"(u) 104 : "m"(v->counter), "rKs21"(a), "rKs21"(u), "1"(result)
105 : "cc", "memory"); 105 : "cc", "memory");
106 106
107 return result; 107 return result;
@@ -137,7 +137,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
137 " mov %1, 1\n" 137 " mov %1, 1\n"
138 "1:" 138 "1:"
139 : "=&r"(tmp), "=&r"(result), "=o"(v->counter) 139 : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
140 : "m"(v->counter), "r"(a), "ir"(u) 140 : "m"(v->counter), "r"(a), "ir"(u), "1"(result)
141 : "cc", "memory"); 141 : "cc", "memory");
142 } 142 }
143 143
diff --git a/include/asm-avr32/unaligned.h b/include/asm-avr32/unaligned.h
index 3042723fcbf..36f5fd43054 100644
--- a/include/asm-avr32/unaligned.h
+++ b/include/asm-avr32/unaligned.h
@@ -7,19 +7,10 @@
7 * words, but halfwords must be halfword-aligned, and doublewords must 7 * words, but halfwords must be halfword-aligned, and doublewords must
8 * be word-aligned. 8 * be word-aligned.
9 * 9 *
10 * TODO: Make all this CPU-specific and optimize. 10 * However, swapped word loads must be word-aligned so we can't
11 * optimize word loads in general.
11 */ 12 */
12 13
13#include <linux/string.h> 14#include <asm-generic/unaligned.h>
14
15/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
16
17#define get_unaligned(ptr) \
18 ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
19
20#define put_unaligned(val, ptr) \
21 ({ __typeof__(*(ptr)) __tmp = (val); \
22 memmove((ptr), &__tmp, sizeof(*(ptr))); \
23 (void)0; })
24 15
25#endif /* __ASM_AVR32_UNALIGNED_H */ 16#endif /* __ASM_AVR32_UNALIGNED_H */