diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
commit | e758936e02700ff88a0b08b722a3847b95283ef2 (patch) | |
tree | 50c919bef1b459a778b85159d5929de95b6c4a01 /arch/avr32 | |
parent | 239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff) | |
parent | 4480f15b3306f43bbb0310d461142b4e897ca45b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
include/asm-x86/statfs.h
Diffstat (limited to 'arch/avr32')
31 files changed, 820 insertions, 274 deletions
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index b8286f1ce854..6c54580a66df 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/etherdevice.h> | 11 | #include <linux/etherdevice.h> |
12 | #include <linux/gpio.h> | ||
12 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
13 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
14 | #include <linux/i2c-gpio.h> | 15 | #include <linux/i2c-gpio.h> |
@@ -53,8 +54,11 @@ static struct spi_board_info spi0_board_info[] __initdata = { | |||
53 | }; | 54 | }; |
54 | 55 | ||
55 | static struct mci_platform_data __initdata mci0_data = { | 56 | static struct mci_platform_data __initdata mci0_data = { |
56 | .detect_pin = GPIO_PIN_PC(25), | 57 | .slot[0] = { |
57 | .wp_pin = GPIO_PIN_PE(0), | 58 | .bus_width = 4, |
59 | .detect_pin = GPIO_PIN_PC(25), | ||
60 | .wp_pin = GPIO_PIN_PE(0), | ||
61 | }, | ||
58 | }; | 62 | }; |
59 | 63 | ||
60 | /* | 64 | /* |
@@ -190,7 +194,7 @@ static int __init atngw100_init(void) | |||
190 | * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus), | 194 | * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus), |
191 | * but it's not available off-board. | 195 | * but it's not available off-board. |
192 | */ | 196 | */ |
193 | at32_select_periph(GPIO_PIN_PB(28), 0, AT32_GPIOF_PULLUP); | 197 | at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP); |
194 | at32_select_gpio(i2c_gpio_data.sda_pin, | 198 | at32_select_gpio(i2c_gpio_data.sda_pin, |
195 | AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | 199 | AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); |
196 | at32_select_gpio(i2c_gpio_data.scl_pin, | 200 | at32_select_gpio(i2c_gpio_data.scl_pin, |
@@ -204,6 +208,15 @@ postcore_initcall(atngw100_init); | |||
204 | 208 | ||
205 | static int __init atngw100_arch_init(void) | 209 | static int __init atngw100_arch_init(void) |
206 | { | 210 | { |
211 | /* PB30 is the otherwise unused jumper on the mainboard, with an | ||
212 | * external pullup; the jumper grounds it. Use it however you | ||
213 | * like, including letting U-Boot or Linux tweak boot sequences. | ||
214 | */ | ||
215 | at32_select_gpio(GPIO_PIN_PB(30), 0); | ||
216 | gpio_request(GPIO_PIN_PB(30), "j15"); | ||
217 | gpio_direction_input(GPIO_PIN_PB(30)); | ||
218 | gpio_export(GPIO_PIN_PB(30), false); | ||
219 | |||
207 | /* set_irq_type() after the arch_initcall for EIC has run, and | 220 | /* set_irq_type() after the arch_initcall for EIC has run, and |
208 | * before the I2C subsystem could try using this IRQ. | 221 | * before the I2C subsystem could try using this IRQ. |
209 | */ | 222 | */ |
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index ee4c292683e1..29e5b51a7fd2 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
@@ -232,7 +232,7 @@ static void __init atstk1002_setup_extdac(void) | |||
232 | goto err_set_clk; | 232 | goto err_set_clk; |
233 | } | 233 | } |
234 | 234 | ||
235 | at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); | 235 | at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); |
236 | at73c213_data.dac_clk = gclk; | 236 | at73c213_data.dac_clk = gclk; |
237 | 237 | ||
238 | err_set_clk: | 238 | err_set_clk: |
@@ -264,16 +264,20 @@ void __init setup_board(void) | |||
264 | 264 | ||
265 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | 265 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
266 | 266 | ||
267 | static struct mci_platform_data __initdata mci0_data = { | ||
268 | .slot[0] = { | ||
269 | .bus_width = 4, | ||
270 | |||
267 | /* MMC card detect requires MACB0 *NOT* be used */ | 271 | /* MMC card detect requires MACB0 *NOT* be used */ |
268 | #ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM | 272 | #ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM |
269 | static struct mci_platform_data __initdata mci0_data = { | 273 | .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ |
270 | .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ | 274 | .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ |
271 | .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ | ||
272 | }; | ||
273 | #define MCI_PDATA &mci0_data | ||
274 | #else | 275 | #else |
275 | #define MCI_PDATA NULL | 276 | .detect_pin = -ENODEV, |
277 | .wp_pin = -ENODEV, | ||
276 | #endif /* SW6 for sd{cd,wp} routing */ | 278 | #endif /* SW6 for sd{cd,wp} routing */ |
279 | }, | ||
280 | }; | ||
277 | 281 | ||
278 | #endif /* SW2 for MMC signal routing */ | 282 | #endif /* SW2 for MMC signal routing */ |
279 | 283 | ||
@@ -325,14 +329,15 @@ static int __init atstk1002_init(void) | |||
325 | #ifdef CONFIG_BOARD_ATSTK100X_SPI1 | 329 | #ifdef CONFIG_BOARD_ATSTK100X_SPI1 |
326 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 330 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
327 | #endif | 331 | #endif |
328 | #ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM | 332 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
329 | at32_add_device_mci(0, MCI_PDATA); | 333 | at32_add_device_mci(0, &mci0_data); |
330 | #endif | 334 | #endif |
331 | #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM | 335 | #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM |
332 | set_hw_addr(at32_add_device_eth(1, ð_data[1])); | 336 | set_hw_addr(at32_add_device_eth(1, ð_data[1])); |
333 | #else | 337 | #else |
334 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, | 338 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, |
335 | fbmem_start, fbmem_size, 0); | 339 | fbmem_start, fbmem_size, |
340 | ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL); | ||
336 | #endif | 341 | #endif |
337 | at32_add_device_usba(0, NULL); | 342 | at32_add_device_usba(0, NULL); |
338 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM | 343 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM |
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c index 0cf664174c17..be089d7f37eb 100644 --- a/arch/avr32/boards/atstk1000/atstk1003.c +++ b/arch/avr32/boards/atstk1000/atstk1003.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | 20 | ||
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | #include <asm/atmel-mci.h> | ||
22 | 23 | ||
23 | #include <mach/at32ap700x.h> | 24 | #include <mach/at32ap700x.h> |
24 | #include <mach/board.h> | 25 | #include <mach/board.h> |
@@ -66,6 +67,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { { | |||
66 | } }; | 67 | } }; |
67 | #endif | 68 | #endif |
68 | 69 | ||
70 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | ||
71 | static struct mci_platform_data __initdata mci0_data = { | ||
72 | .slot[0] = { | ||
73 | .bus_width = 4, | ||
74 | .detect_pin = -ENODEV, | ||
75 | .wp_pin = -ENODEV, | ||
76 | }, | ||
77 | }; | ||
78 | #endif | ||
79 | |||
69 | #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC | 80 | #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC |
70 | static void __init atstk1003_setup_extdac(void) | 81 | static void __init atstk1003_setup_extdac(void) |
71 | { | 82 | { |
@@ -84,7 +95,7 @@ static void __init atstk1003_setup_extdac(void) | |||
84 | goto err_set_clk; | 95 | goto err_set_clk; |
85 | } | 96 | } |
86 | 97 | ||
87 | at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); | 98 | at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); |
88 | at73c213_data.dac_clk = gclk; | 99 | at73c213_data.dac_clk = gclk; |
89 | 100 | ||
90 | err_set_clk: | 101 | err_set_clk: |
@@ -154,7 +165,7 @@ static int __init atstk1003_init(void) | |||
154 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 165 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
155 | #endif | 166 | #endif |
156 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | 167 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
157 | at32_add_device_mci(0, NULL); | 168 | at32_add_device_mci(0, &mci0_data); |
158 | #endif | 169 | #endif |
159 | at32_add_device_usba(0, NULL); | 170 | at32_add_device_usba(0, NULL); |
160 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM | 171 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM |
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index 50a5273e5916..248ef237c167 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <video/atmel_lcdc.h> | 21 | #include <video/atmel_lcdc.h> |
22 | 22 | ||
23 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
24 | #include <asm/atmel-mci.h> | ||
24 | 25 | ||
25 | #include <mach/at32ap700x.h> | 26 | #include <mach/at32ap700x.h> |
26 | #include <mach/board.h> | 27 | #include <mach/board.h> |
@@ -71,6 +72,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { { | |||
71 | } }; | 72 | } }; |
72 | #endif | 73 | #endif |
73 | 74 | ||
75 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | ||
76 | static struct mci_platform_data __initdata mci0_data = { | ||
77 | .slot[0] = { | ||
78 | .bus_width = 4, | ||
79 | .detect_pin = -ENODEV, | ||
80 | .wp_pin = -ENODEV, | ||
81 | }, | ||
82 | }; | ||
83 | #endif | ||
84 | |||
74 | #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC | 85 | #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC |
75 | static void __init atstk1004_setup_extdac(void) | 86 | static void __init atstk1004_setup_extdac(void) |
76 | { | 87 | { |
@@ -89,7 +100,7 @@ static void __init atstk1004_setup_extdac(void) | |||
89 | goto err_set_clk; | 100 | goto err_set_clk; |
90 | } | 101 | } |
91 | 102 | ||
92 | at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); | 103 | at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); |
93 | at73c213_data.dac_clk = gclk; | 104 | at73c213_data.dac_clk = gclk; |
94 | 105 | ||
95 | err_set_clk: | 106 | err_set_clk: |
@@ -137,10 +148,11 @@ static int __init atstk1004_init(void) | |||
137 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); | 148 | at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); |
138 | #endif | 149 | #endif |
139 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM | 150 | #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM |
140 | at32_add_device_mci(0, NULL); | 151 | at32_add_device_mci(0, &mci0_data); |
141 | #endif | 152 | #endif |
142 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, | 153 | at32_add_device_lcdc(0, &atstk1000_lcdc_data, |
143 | fbmem_start, fbmem_size, 0); | 154 | fbmem_start, fbmem_size, |
155 | ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL); | ||
144 | at32_add_device_usba(0, NULL); | 156 | at32_add_device_usba(0, NULL); |
145 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM | 157 | #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM |
146 | at32_add_device_ssc(0, ATMEL_SSC_TX); | 158 | at32_add_device_ssc(0, ATMEL_SSC_TX); |
diff --git a/arch/avr32/boot/images/.gitignore b/arch/avr32/boot/images/.gitignore new file mode 100644 index 000000000000..64ea9d0141d2 --- /dev/null +++ b/arch/avr32/boot/images/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | uImage | ||
2 | uImage.srec | ||
3 | vmlinux.cso | ||
4 | sfdwarf.log | ||
diff --git a/arch/avr32/include/asm/atmel-mci.h b/arch/avr32/include/asm/atmel-mci.h index c2ea6e1c9aa1..59f3fadd0b68 100644 --- a/arch/avr32/include/asm/atmel-mci.h +++ b/arch/avr32/include/asm/atmel-mci.h | |||
@@ -1,9 +1,39 @@ | |||
1 | #ifndef __ASM_AVR32_ATMEL_MCI_H | 1 | #ifndef __ASM_AVR32_ATMEL_MCI_H |
2 | #define __ASM_AVR32_ATMEL_MCI_H | 2 | #define __ASM_AVR32_ATMEL_MCI_H |
3 | 3 | ||
4 | struct mci_platform_data { | 4 | #define ATMEL_MCI_MAX_NR_SLOTS 2 |
5 | |||
6 | struct dma_slave; | ||
7 | |||
8 | /** | ||
9 | * struct mci_slot_pdata - board-specific per-slot configuration | ||
10 | * @bus_width: Number of data lines wired up the slot | ||
11 | * @detect_pin: GPIO pin wired to the card detect switch | ||
12 | * @wp_pin: GPIO pin wired to the write protect sensor | ||
13 | * | ||
14 | * If a given slot is not present on the board, @bus_width should be | ||
15 | * set to 0. The other fields are ignored in this case. | ||
16 | * | ||
17 | * Any pins that aren't available should be set to a negative value. | ||
18 | * | ||
19 | * Note that support for multiple slots is experimental -- some cards | ||
20 | * might get upset if we don't get the clock management exactly right. | ||
21 | * But in most cases, it should work just fine. | ||
22 | */ | ||
23 | struct mci_slot_pdata { | ||
24 | unsigned int bus_width; | ||
5 | int detect_pin; | 25 | int detect_pin; |
6 | int wp_pin; | 26 | int wp_pin; |
7 | }; | 27 | }; |
8 | 28 | ||
29 | /** | ||
30 | * struct mci_platform_data - board-specific MMC/SDcard configuration | ||
31 | * @dma_slave: DMA slave interface to use in data transfers, or NULL. | ||
32 | * @slot: Per-slot configuration data. | ||
33 | */ | ||
34 | struct mci_platform_data { | ||
35 | struct dma_slave *dma_slave; | ||
36 | struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; | ||
37 | }; | ||
38 | |||
9 | #endif /* __ASM_AVR32_ATMEL_MCI_H */ | 39 | #endif /* __ASM_AVR32_ATMEL_MCI_H */ |
diff --git a/arch/avr32/include/asm/byteorder.h b/arch/avr32/include/asm/byteorder.h index d77b48ba7338..8e3af02076dd 100644 --- a/arch/avr32/include/asm/byteorder.h +++ b/arch/avr32/include/asm/byteorder.h | |||
@@ -7,6 +7,9 @@ | |||
7 | #include <asm/types.h> | 7 | #include <asm/types.h> |
8 | #include <linux/compiler.h> | 8 | #include <linux/compiler.h> |
9 | 9 | ||
10 | #define __BIG_ENDIAN | ||
11 | #define __SWAB_64_THRU_32__ | ||
12 | |||
10 | #ifdef __CHECKER__ | 13 | #ifdef __CHECKER__ |
11 | extern unsigned long __builtin_bswap_32(unsigned long x); | 14 | extern unsigned long __builtin_bswap_32(unsigned long x); |
12 | extern unsigned short __builtin_bswap_16(unsigned short x); | 15 | extern unsigned short __builtin_bswap_16(unsigned short x); |
@@ -17,15 +20,18 @@ extern unsigned short __builtin_bswap_16(unsigned short x); | |||
17 | * the result. | 20 | * the result. |
18 | */ | 21 | */ |
19 | #if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2) | 22 | #if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2) |
20 | #define __arch__swab32(x) __builtin_bswap_32(x) | 23 | static inline __attribute_const__ __u16 __arch_swab16(__u16 val) |
21 | #define __arch__swab16(x) __builtin_bswap_16(x) | 24 | { |
22 | #endif | 25 | return __builtin_bswap_16(val); |
26 | } | ||
27 | #define __arch_swab16 __arch_swab16 | ||
23 | 28 | ||
24 | #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) | 29 | static inline __attribute_const__ __u32 __arch_swab32(__u32 val) |
25 | # define __BYTEORDER_HAS_U64__ | 30 | { |
26 | # define __SWAB_64_THRU_32__ | 31 | return __builtin_bswap_32(val); |
32 | } | ||
33 | #define __arch_swab32 __arch_swab32 | ||
27 | #endif | 34 | #endif |
28 | 35 | ||
29 | #include <linux/byteorder/big_endian.h> | 36 | #include <linux/byteorder.h> |
30 | |||
31 | #endif /* __ASM_AVR32_BYTEORDER_H */ | 37 | #endif /* __ASM_AVR32_BYTEORDER_H */ |
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h index a520f77ead96..22c97ef92201 100644 --- a/arch/avr32/include/asm/io.h +++ b/arch/avr32/include/asm/io.h | |||
@@ -160,6 +160,14 @@ BUILDIO_IOPORT(l, u32) | |||
160 | #define readw_relaxed readw | 160 | #define readw_relaxed readw |
161 | #define readl_relaxed readl | 161 | #define readl_relaxed readl |
162 | 162 | ||
163 | #define readb_be __raw_readb | ||
164 | #define readw_be __raw_readw | ||
165 | #define readl_be __raw_readl | ||
166 | |||
167 | #define writeb_be __raw_writeb | ||
168 | #define writew_be __raw_writew | ||
169 | #define writel_be __raw_writel | ||
170 | |||
163 | #define __BUILD_MEMORY_STRING(bwl, type) \ | 171 | #define __BUILD_MEMORY_STRING(bwl, type) \ |
164 | static inline void writes##bwl(volatile void __iomem *addr, \ | 172 | static inline void writes##bwl(volatile void __iomem *addr, \ |
165 | const void *data, unsigned int count) \ | 173 | const void *data, unsigned int count) \ |
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore new file mode 100644 index 000000000000..c5f676c3c224 --- /dev/null +++ b/arch/avr32/kernel/.gitignore | |||
@@ -0,0 +1 @@ | |||
vmlinux.lds | |||
diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c index e4796c67a831..d6a8193a1d2f 100644 --- a/arch/avr32/kernel/asm-offsets.c +++ b/arch/avr32/kernel/asm-offsets.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * to extract and format the required data. | 4 | * to extract and format the required data. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/mm.h> | ||
8 | #include <linux/sched.h> | ||
7 | #include <linux/thread_info.h> | 9 | #include <linux/thread_info.h> |
8 | #include <linux/kbuild.h> | 10 | #include <linux/kbuild.h> |
9 | 11 | ||
@@ -17,4 +19,8 @@ void foo(void) | |||
17 | OFFSET(TI_rar_saved, thread_info, rar_saved); | 19 | OFFSET(TI_rar_saved, thread_info, rar_saved); |
18 | OFFSET(TI_rsr_saved, thread_info, rsr_saved); | 20 | OFFSET(TI_rsr_saved, thread_info, rsr_saved); |
19 | OFFSET(TI_restart_block, thread_info, restart_block); | 21 | OFFSET(TI_restart_block, thread_info, restart_block); |
22 | BLANK(); | ||
23 | OFFSET(TSK_active_mm, task_struct, active_mm); | ||
24 | BLANK(); | ||
25 | OFFSET(MM_pgd, mm_struct, pgd); | ||
20 | } | 26 | } |
diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index 84a7d44edc67..11e310c567a9 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c | |||
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(find_first_zero_bit); | |||
58 | EXPORT_SYMBOL(find_next_zero_bit); | 58 | EXPORT_SYMBOL(find_next_zero_bit); |
59 | EXPORT_SYMBOL(find_first_bit); | 59 | EXPORT_SYMBOL(find_first_bit); |
60 | EXPORT_SYMBOL(find_next_bit); | 60 | EXPORT_SYMBOL(find_next_bit); |
61 | EXPORT_SYMBOL(generic_find_next_le_bit); | ||
61 | EXPORT_SYMBOL(generic_find_next_zero_le_bit); | 62 | EXPORT_SYMBOL(generic_find_next_zero_le_bit); |
62 | 63 | ||
63 | /* I/O primitives (lib/io-*.S) */ | 64 | /* I/O primitives (lib/io-*.S) */ |
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 2b398cae110c..33d49377b8be 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S | |||
@@ -334,9 +334,64 @@ save_full_context_ex: | |||
334 | 334 | ||
335 | /* Low-level exception handlers */ | 335 | /* Low-level exception handlers */ |
336 | handle_critical: | 336 | handle_critical: |
337 | /* | ||
338 | * AT32AP700x errata: | ||
339 | * | ||
340 | * After a Java stack overflow or underflow trap, any CPU | ||
341 | * memory access may cause erratic behavior. This will happen | ||
342 | * when the four least significant bits of the JOSP system | ||
343 | * register contains any value between 9 and 15 (inclusive). | ||
344 | * | ||
345 | * Possible workarounds: | ||
346 | * - Don't use the Java Extension Module | ||
347 | * - Ensure that the stack overflow and underflow trap | ||
348 | * handlers do not do any memory access or trigger any | ||
349 | * exceptions before the overflow/underflow condition is | ||
350 | * cleared (by incrementing or decrementing the JOSP) | ||
351 | * - Make sure that JOSP does not contain any problematic | ||
352 | * value before doing any exception or interrupt | ||
353 | * processing. | ||
354 | * - Set up a critical exception handler which writes a | ||
355 | * known-to-be-safe value, e.g. 4, to JOSP before doing | ||
356 | * any further processing. | ||
357 | * | ||
358 | * We'll use the last workaround for now since we cannot | ||
359 | * guarantee that user space processes don't use Java mode. | ||
360 | * Non-well-behaving userland will be terminated with extreme | ||
361 | * prejudice. | ||
362 | */ | ||
363 | #ifdef CONFIG_CPU_AT32AP700X | ||
364 | /* | ||
365 | * There's a chance we can't touch memory, so temporarily | ||
366 | * borrow PTBR to save the stack pointer while we fix things | ||
367 | * up... | ||
368 | */ | ||
369 | mtsr SYSREG_PTBR, sp | ||
370 | mov sp, 4 | ||
371 | mtsr SYSREG_JOSP, sp | ||
372 | mfsr sp, SYSREG_PTBR | ||
373 | sub pc, -2 | ||
374 | |||
375 | /* Push most of pt_regs on stack. We'll do the rest later */ | ||
337 | sub sp, 4 | 376 | sub sp, 4 |
338 | stmts --sp, r0-lr | 377 | pushm r0-r12 |
339 | rcall save_full_context_ex | 378 | |
379 | /* PTBR mirrors current_thread_info()->task->active_mm->pgd */ | ||
380 | get_thread_info r0 | ||
381 | ld.w r1, r0[TI_task] | ||
382 | ld.w r2, r1[TSK_active_mm] | ||
383 | ld.w r3, r2[MM_pgd] | ||
384 | mtsr SYSREG_PTBR, r3 | ||
385 | #else | ||
386 | sub sp, 4 | ||
387 | pushm r0-r12 | ||
388 | #endif | ||
389 | sub r0, sp, -(14 * 4) | ||
390 | mov r1, lr | ||
391 | mfsr r2, SYSREG_RAR_EX | ||
392 | mfsr r3, SYSREG_RSR_EX | ||
393 | pushm r0-r3 | ||
394 | |||
340 | mfsr r12, SYSREG_ECR | 395 | mfsr r12, SYSREG_ECR |
341 | mov r11, sp | 396 | mov r11, sp |
342 | rcall do_critical_exception | 397 | rcall do_critical_exception |
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 2c08ac992ac3..134d5302b6dd 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/kallsyms.h> | 10 | #include <linux/kallsyms.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/pm.h> | ||
12 | #include <linux/ptrace.h> | 13 | #include <linux/ptrace.h> |
13 | #include <linux/reboot.h> | 14 | #include <linux/reboot.h> |
14 | #include <linux/tick.h> | 15 | #include <linux/tick.h> |
@@ -20,7 +21,7 @@ | |||
20 | 21 | ||
21 | #include <mach/pm.h> | 22 | #include <mach/pm.h> |
22 | 23 | ||
23 | void (*pm_power_off)(void) = NULL; | 24 | void (*pm_power_off)(void); |
24 | EXPORT_SYMBOL(pm_power_off); | 25 | EXPORT_SYMBOL(pm_power_off); |
25 | 26 | ||
26 | /* | 27 | /* |
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index d8e623c426c1..5c7083916c33 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c | |||
@@ -283,6 +283,25 @@ static int __init early_parse_fbmem(char *p) | |||
283 | } | 283 | } |
284 | early_param("fbmem", early_parse_fbmem); | 284 | early_param("fbmem", early_parse_fbmem); |
285 | 285 | ||
286 | /* | ||
287 | * Pick out the memory size. We look for mem=size@start, | ||
288 | * where start and size are "size[KkMmGg]" | ||
289 | */ | ||
290 | static int __init early_mem(char *p) | ||
291 | { | ||
292 | resource_size_t size, start; | ||
293 | |||
294 | start = system_ram->start; | ||
295 | size = memparse(p, &p); | ||
296 | if (*p == '@') | ||
297 | start = memparse(p + 1, &p); | ||
298 | |||
299 | system_ram->start = start; | ||
300 | system_ram->end = system_ram->start + size - 1; | ||
301 | return 0; | ||
302 | } | ||
303 | early_param("mem", early_mem); | ||
304 | |||
286 | static int __init parse_tag_core(struct tag *tag) | 305 | static int __init parse_tag_core(struct tag *tag) |
287 | { | 306 | { |
288 | if (tag->hdr.size > 2) { | 307 | if (tag->hdr.size > 2) { |
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S index 890286a1e62b..673178e235f3 100644 --- a/arch/avr32/kernel/syscall-stubs.S +++ b/arch/avr32/kernel/syscall-stubs.S | |||
@@ -109,3 +109,12 @@ __sys_epoll_pwait: | |||
109 | rcall sys_epoll_pwait | 109 | rcall sys_epoll_pwait |
110 | sub sp, -4 | 110 | sub sp, -4 |
111 | popm pc | 111 | popm pc |
112 | |||
113 | .global __sys_sync_file_range | ||
114 | .type __sys_sync_file_range,@function | ||
115 | __sys_sync_file_range: | ||
116 | pushm lr | ||
117 | st.w --sp, ARG6 | ||
118 | rcall sys_sync_file_range | ||
119 | sub sp, -4 | ||
120 | popm pc | ||
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index 478bda4c4a09..7ee0057613b3 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S | |||
@@ -275,7 +275,7 @@ sys_call_table: | |||
275 | .long sys_set_robust_list | 275 | .long sys_set_robust_list |
276 | .long sys_get_robust_list /* 260 */ | 276 | .long sys_get_robust_list /* 260 */ |
277 | .long __sys_splice | 277 | .long __sys_splice |
278 | .long sys_sync_file_range | 278 | .long __sys_sync_file_range |
279 | .long sys_tee | 279 | .long sys_tee |
280 | .long sys_vmsplice | 280 | .long sys_vmsplice |
281 | .long __sys_epoll_pwait /* 265 */ | 281 | .long __sys_epoll_pwait /* 265 */ |
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index b835c4c01368..0d987373bc01 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c | |||
@@ -116,15 +116,15 @@ asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) | |||
116 | switch (ret) { | 116 | switch (ret) { |
117 | case NOTIFY_OK: | 117 | case NOTIFY_OK: |
118 | case NOTIFY_STOP: | 118 | case NOTIFY_STOP: |
119 | return; | 119 | break; |
120 | case NOTIFY_BAD: | 120 | case NOTIFY_BAD: |
121 | die("Fatal Non-Maskable Interrupt", regs, SIGINT); | 121 | die("Fatal Non-Maskable Interrupt", regs, SIGINT); |
122 | default: | 122 | default: |
123 | printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); | ||
124 | nmi_disable(); | ||
123 | break; | 125 | break; |
124 | } | 126 | } |
125 | 127 | nmi_exit(); | |
126 | printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); | ||
127 | nmi_disable(); | ||
128 | } | 128 | } |
129 | 129 | ||
130 | asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) | 130 | asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) |
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S index c6b91dee857c..997b33b2288a 100644 --- a/arch/avr32/lib/findbit.S +++ b/arch/avr32/lib/findbit.S | |||
@@ -123,6 +123,36 @@ ENTRY(find_next_bit) | |||
123 | brgt 1b | 123 | brgt 1b |
124 | retal r11 | 124 | retal r11 |
125 | 125 | ||
126 | ENTRY(generic_find_next_le_bit) | ||
127 | lsr r8, r10, 5 | ||
128 | sub r9, r11, r10 | ||
129 | retle r11 | ||
130 | |||
131 | lsl r8, 2 | ||
132 | add r12, r8 | ||
133 | andl r10, 31, COH | ||
134 | breq 1f | ||
135 | |||
136 | /* offset is not word-aligned. Handle the first (32 - r10) bits */ | ||
137 | ldswp.w r8, r12[0] | ||
138 | sub r12, -4 | ||
139 | lsr r8, r8, r10 | ||
140 | brne .L_found | ||
141 | |||
142 | /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ | ||
143 | add r9, r10 | ||
144 | sub r9, 32 | ||
145 | retle r11 | ||
146 | |||
147 | /* Main loop. offset must be word-aligned */ | ||
148 | 1: ldswp.w r8, r12[0] | ||
149 | cp.w r8, 0 | ||
150 | brne .L_found | ||
151 | sub r12, -4 | ||
152 | sub r9, 32 | ||
153 | brgt 1b | ||
154 | retal r11 | ||
155 | |||
126 | ENTRY(generic_find_next_zero_le_bit) | 156 | ENTRY(generic_find_next_zero_le_bit) |
127 | lsr r8, r10, 5 | 157 | lsr r8, r10, 5 |
128 | sub r9, r11, r10 | 158 | sub r9, r11, r10 |
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index e01dbe4ebb40..813b6844cdf6 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -82,8 +82,9 @@ static struct platform_device _name##_id##_device = { \ | |||
82 | .num_resources = ARRAY_SIZE(_name##_id##_resource), \ | 82 | .num_resources = ARRAY_SIZE(_name##_id##_resource), \ |
83 | } | 83 | } |
84 | 84 | ||
85 | #define select_peripheral(pin, periph, flags) \ | 85 | #define select_peripheral(port, pin_mask, periph, flags) \ |
86 | at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags) | 86 | at32_select_periph(GPIO_##port##_BASE, pin_mask, \ |
87 | GPIO_##periph, flags) | ||
87 | 88 | ||
88 | #define DEV_CLK(_name, devname, bus, _index) \ | 89 | #define DEV_CLK(_name, devname, bus, _index) \ |
89 | static struct clk devname##_##_name = { \ | 90 | static struct clk devname##_##_name = { \ |
@@ -871,6 +872,7 @@ static struct clk atmel_psif1_pclk = { | |||
871 | struct platform_device *__init at32_add_device_psif(unsigned int id) | 872 | struct platform_device *__init at32_add_device_psif(unsigned int id) |
872 | { | 873 | { |
873 | struct platform_device *pdev; | 874 | struct platform_device *pdev; |
875 | u32 pin_mask; | ||
874 | 876 | ||
875 | if (!(id == 0 || id == 1)) | 877 | if (!(id == 0 || id == 1)) |
876 | return NULL; | 878 | return NULL; |
@@ -881,20 +883,22 @@ struct platform_device *__init at32_add_device_psif(unsigned int id) | |||
881 | 883 | ||
882 | switch (id) { | 884 | switch (id) { |
883 | case 0: | 885 | case 0: |
886 | pin_mask = (1 << 8) | (1 << 9); /* CLOCK & DATA */ | ||
887 | |||
884 | if (platform_device_add_resources(pdev, atmel_psif0_resource, | 888 | if (platform_device_add_resources(pdev, atmel_psif0_resource, |
885 | ARRAY_SIZE(atmel_psif0_resource))) | 889 | ARRAY_SIZE(atmel_psif0_resource))) |
886 | goto err_add_resources; | 890 | goto err_add_resources; |
887 | atmel_psif0_pclk.dev = &pdev->dev; | 891 | atmel_psif0_pclk.dev = &pdev->dev; |
888 | select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */ | 892 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); |
889 | select_peripheral(PA(9), PERIPH_A, 0); /* DATA */ | ||
890 | break; | 893 | break; |
891 | case 1: | 894 | case 1: |
895 | pin_mask = (1 << 11) | (1 << 12); /* CLOCK & DATA */ | ||
896 | |||
892 | if (platform_device_add_resources(pdev, atmel_psif1_resource, | 897 | if (platform_device_add_resources(pdev, atmel_psif1_resource, |
893 | ARRAY_SIZE(atmel_psif1_resource))) | 898 | ARRAY_SIZE(atmel_psif1_resource))) |
894 | goto err_add_resources; | 899 | goto err_add_resources; |
895 | atmel_psif1_pclk.dev = &pdev->dev; | 900 | atmel_psif1_pclk.dev = &pdev->dev; |
896 | select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */ | 901 | select_peripheral(PIOB, pin_mask, PERIPH_A, 0); |
897 | select_peripheral(PB(12), PERIPH_A, 0); /* DATA */ | ||
898 | break; | 902 | break; |
899 | default: | 903 | default: |
900 | return NULL; | 904 | return NULL; |
@@ -958,26 +962,30 @@ DEV_CLK(usart, atmel_usart3, pba, 6); | |||
958 | 962 | ||
959 | static inline void configure_usart0_pins(void) | 963 | static inline void configure_usart0_pins(void) |
960 | { | 964 | { |
961 | select_peripheral(PA(8), PERIPH_B, 0); /* RXD */ | 965 | u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */ |
962 | select_peripheral(PA(9), PERIPH_B, 0); /* TXD */ | 966 | |
967 | select_peripheral(PIOA, pin_mask, PERIPH_B, 0); | ||
963 | } | 968 | } |
964 | 969 | ||
965 | static inline void configure_usart1_pins(void) | 970 | static inline void configure_usart1_pins(void) |
966 | { | 971 | { |
967 | select_peripheral(PA(17), PERIPH_A, 0); /* RXD */ | 972 | u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */ |
968 | select_peripheral(PA(18), PERIPH_A, 0); /* TXD */ | 973 | |
974 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); | ||
969 | } | 975 | } |
970 | 976 | ||
971 | static inline void configure_usart2_pins(void) | 977 | static inline void configure_usart2_pins(void) |
972 | { | 978 | { |
973 | select_peripheral(PB(26), PERIPH_B, 0); /* RXD */ | 979 | u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */ |
974 | select_peripheral(PB(27), PERIPH_B, 0); /* TXD */ | 980 | |
981 | select_peripheral(PIOB, pin_mask, PERIPH_B, 0); | ||
975 | } | 982 | } |
976 | 983 | ||
977 | static inline void configure_usart3_pins(void) | 984 | static inline void configure_usart3_pins(void) |
978 | { | 985 | { |
979 | select_peripheral(PB(18), PERIPH_B, 0); /* RXD */ | 986 | u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */ |
980 | select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ | 987 | |
988 | select_peripheral(PIOB, pin_mask, PERIPH_B, 0); | ||
981 | } | 989 | } |
982 | 990 | ||
983 | static struct platform_device *__initdata at32_usarts[4]; | 991 | static struct platform_device *__initdata at32_usarts[4]; |
@@ -1057,59 +1065,69 @@ struct platform_device *__init | |||
1057 | at32_add_device_eth(unsigned int id, struct eth_platform_data *data) | 1065 | at32_add_device_eth(unsigned int id, struct eth_platform_data *data) |
1058 | { | 1066 | { |
1059 | struct platform_device *pdev; | 1067 | struct platform_device *pdev; |
1068 | u32 pin_mask; | ||
1060 | 1069 | ||
1061 | switch (id) { | 1070 | switch (id) { |
1062 | case 0: | 1071 | case 0: |
1063 | pdev = &macb0_device; | 1072 | pdev = &macb0_device; |
1064 | 1073 | ||
1065 | select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */ | 1074 | pin_mask = (1 << 3); /* TXD0 */ |
1066 | select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */ | 1075 | pin_mask |= (1 << 4); /* TXD1 */ |
1067 | select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */ | 1076 | pin_mask |= (1 << 7); /* TXEN */ |
1068 | select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */ | 1077 | pin_mask |= (1 << 8); /* TXCK */ |
1069 | select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */ | 1078 | pin_mask |= (1 << 9); /* RXD0 */ |
1070 | select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */ | 1079 | pin_mask |= (1 << 10); /* RXD1 */ |
1071 | select_peripheral(PC(13), PERIPH_A, 0); /* RXER */ | 1080 | pin_mask |= (1 << 13); /* RXER */ |
1072 | select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */ | 1081 | pin_mask |= (1 << 15); /* RXDV */ |
1073 | select_peripheral(PC(16), PERIPH_A, 0); /* MDC */ | 1082 | pin_mask |= (1 << 16); /* MDC */ |
1074 | select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */ | 1083 | pin_mask |= (1 << 17); /* MDIO */ |
1075 | 1084 | ||
1076 | if (!data->is_rmii) { | 1085 | if (!data->is_rmii) { |
1077 | select_peripheral(PC(0), PERIPH_A, 0); /* COL */ | 1086 | pin_mask |= (1 << 0); /* COL */ |
1078 | select_peripheral(PC(1), PERIPH_A, 0); /* CRS */ | 1087 | pin_mask |= (1 << 1); /* CRS */ |
1079 | select_peripheral(PC(2), PERIPH_A, 0); /* TXER */ | 1088 | pin_mask |= (1 << 2); /* TXER */ |
1080 | select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */ | 1089 | pin_mask |= (1 << 5); /* TXD2 */ |
1081 | select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */ | 1090 | pin_mask |= (1 << 6); /* TXD3 */ |
1082 | select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */ | 1091 | pin_mask |= (1 << 11); /* RXD2 */ |
1083 | select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */ | 1092 | pin_mask |= (1 << 12); /* RXD3 */ |
1084 | select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */ | 1093 | pin_mask |= (1 << 14); /* RXCK */ |
1085 | select_peripheral(PC(18), PERIPH_A, 0); /* SPD */ | 1094 | pin_mask |= (1 << 18); /* SPD */ |
1086 | } | 1095 | } |
1096 | |||
1097 | select_peripheral(PIOC, pin_mask, PERIPH_A, 0); | ||
1098 | |||
1087 | break; | 1099 | break; |
1088 | 1100 | ||
1089 | case 1: | 1101 | case 1: |
1090 | pdev = &macb1_device; | 1102 | pdev = &macb1_device; |
1091 | 1103 | ||
1092 | select_peripheral(PD(13), PERIPH_B, 0); /* TXD0 */ | 1104 | pin_mask = (1 << 13); /* TXD0 */ |
1093 | select_peripheral(PD(14), PERIPH_B, 0); /* TXD1 */ | 1105 | pin_mask |= (1 << 14); /* TXD1 */ |
1094 | select_peripheral(PD(11), PERIPH_B, 0); /* TXEN */ | 1106 | pin_mask |= (1 << 11); /* TXEN */ |
1095 | select_peripheral(PD(12), PERIPH_B, 0); /* TXCK */ | 1107 | pin_mask |= (1 << 12); /* TXCK */ |
1096 | select_peripheral(PD(10), PERIPH_B, 0); /* RXD0 */ | 1108 | pin_mask |= (1 << 10); /* RXD0 */ |
1097 | select_peripheral(PD(6), PERIPH_B, 0); /* RXD1 */ | 1109 | pin_mask |= (1 << 6); /* RXD1 */ |
1098 | select_peripheral(PD(5), PERIPH_B, 0); /* RXER */ | 1110 | pin_mask |= (1 << 5); /* RXER */ |
1099 | select_peripheral(PD(4), PERIPH_B, 0); /* RXDV */ | 1111 | pin_mask |= (1 << 4); /* RXDV */ |
1100 | select_peripheral(PD(3), PERIPH_B, 0); /* MDC */ | 1112 | pin_mask |= (1 << 3); /* MDC */ |
1101 | select_peripheral(PD(2), PERIPH_B, 0); /* MDIO */ | 1113 | pin_mask |= (1 << 2); /* MDIO */ |
1114 | |||
1115 | if (!data->is_rmii) | ||
1116 | pin_mask |= (1 << 15); /* SPD */ | ||
1117 | |||
1118 | select_peripheral(PIOD, pin_mask, PERIPH_B, 0); | ||
1102 | 1119 | ||
1103 | if (!data->is_rmii) { | 1120 | if (!data->is_rmii) { |
1104 | select_peripheral(PC(19), PERIPH_B, 0); /* COL */ | 1121 | pin_mask = (1 << 19); /* COL */ |
1105 | select_peripheral(PC(23), PERIPH_B, 0); /* CRS */ | 1122 | pin_mask |= (1 << 23); /* CRS */ |
1106 | select_peripheral(PC(26), PERIPH_B, 0); /* TXER */ | 1123 | pin_mask |= (1 << 26); /* TXER */ |
1107 | select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */ | 1124 | pin_mask |= (1 << 27); /* TXD2 */ |
1108 | select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */ | 1125 | pin_mask |= (1 << 28); /* TXD3 */ |
1109 | select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */ | 1126 | pin_mask |= (1 << 29); /* RXD2 */ |
1110 | select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */ | 1127 | pin_mask |= (1 << 30); /* RXD3 */ |
1111 | select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */ | 1128 | pin_mask |= (1 << 24); /* RXCK */ |
1112 | select_peripheral(PD(15), PERIPH_B, 0); /* SPD */ | 1129 | |
1130 | select_peripheral(PIOC, pin_mask, PERIPH_B, 0); | ||
1113 | } | 1131 | } |
1114 | break; | 1132 | break; |
1115 | 1133 | ||
@@ -1177,23 +1195,28 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) | |||
1177 | { GPIO_PIN_PB(2), GPIO_PIN_PB(3), | 1195 | { GPIO_PIN_PB(2), GPIO_PIN_PB(3), |
1178 | GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; | 1196 | GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; |
1179 | struct platform_device *pdev; | 1197 | struct platform_device *pdev; |
1198 | u32 pin_mask; | ||
1180 | 1199 | ||
1181 | switch (id) { | 1200 | switch (id) { |
1182 | case 0: | 1201 | case 0: |
1183 | pdev = &atmel_spi0_device; | 1202 | pdev = &atmel_spi0_device; |
1203 | pin_mask = (1 << 1) | (1 << 2); /* MOSI & SCK */ | ||
1204 | |||
1184 | /* pullup MISO so a level is always defined */ | 1205 | /* pullup MISO so a level is always defined */ |
1185 | select_peripheral(PA(0), PERIPH_A, AT32_GPIOF_PULLUP); | 1206 | select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP); |
1186 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ | 1207 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); |
1187 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ | 1208 | |
1188 | at32_spi_setup_slaves(0, b, n, spi0_pins); | 1209 | at32_spi_setup_slaves(0, b, n, spi0_pins); |
1189 | break; | 1210 | break; |
1190 | 1211 | ||
1191 | case 1: | 1212 | case 1: |
1192 | pdev = &atmel_spi1_device; | 1213 | pdev = &atmel_spi1_device; |
1214 | pin_mask = (1 << 1) | (1 << 5); /* MOSI */ | ||
1215 | |||
1193 | /* pullup MISO so a level is always defined */ | 1216 | /* pullup MISO so a level is always defined */ |
1194 | select_peripheral(PB(0), PERIPH_B, AT32_GPIOF_PULLUP); | 1217 | select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP); |
1195 | select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ | 1218 | select_peripheral(PIOB, pin_mask, PERIPH_B, 0); |
1196 | select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ | 1219 | |
1197 | at32_spi_setup_slaves(1, b, n, spi1_pins); | 1220 | at32_spi_setup_slaves(1, b, n, spi1_pins); |
1198 | break; | 1221 | break; |
1199 | 1222 | ||
@@ -1226,6 +1249,7 @@ struct platform_device *__init at32_add_device_twi(unsigned int id, | |||
1226 | unsigned int n) | 1249 | unsigned int n) |
1227 | { | 1250 | { |
1228 | struct platform_device *pdev; | 1251 | struct platform_device *pdev; |
1252 | u32 pin_mask; | ||
1229 | 1253 | ||
1230 | if (id != 0) | 1254 | if (id != 0) |
1231 | return NULL; | 1255 | return NULL; |
@@ -1238,8 +1262,9 @@ struct platform_device *__init at32_add_device_twi(unsigned int id, | |||
1238 | ARRAY_SIZE(atmel_twi0_resource))) | 1262 | ARRAY_SIZE(atmel_twi0_resource))) |
1239 | goto err_add_resources; | 1263 | goto err_add_resources; |
1240 | 1264 | ||
1241 | select_peripheral(PA(6), PERIPH_A, 0); /* SDA */ | 1265 | pin_mask = (1 << 6) | (1 << 7); /* SDA & SDL */ |
1242 | select_peripheral(PA(7), PERIPH_A, 0); /* SDL */ | 1266 | |
1267 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); | ||
1243 | 1268 | ||
1244 | atmel_twi0_pclk.dev = &pdev->dev; | 1269 | atmel_twi0_pclk.dev = &pdev->dev; |
1245 | 1270 | ||
@@ -1272,10 +1297,16 @@ static struct clk atmel_mci0_pclk = { | |||
1272 | struct platform_device *__init | 1297 | struct platform_device *__init |
1273 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | 1298 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data) |
1274 | { | 1299 | { |
1275 | struct mci_platform_data _data; | ||
1276 | struct platform_device *pdev; | 1300 | struct platform_device *pdev; |
1301 | struct dw_dma_slave *dws; | ||
1302 | u32 pioa_mask; | ||
1303 | u32 piob_mask; | ||
1277 | 1304 | ||
1278 | if (id != 0) | 1305 | if (id != 0 || !data) |
1306 | return NULL; | ||
1307 | |||
1308 | /* Must have at least one usable slot */ | ||
1309 | if (!data->slot[0].bus_width && !data->slot[1].bus_width) | ||
1279 | return NULL; | 1310 | return NULL; |
1280 | 1311 | ||
1281 | pdev = platform_device_alloc("atmel_mci", id); | 1312 | pdev = platform_device_alloc("atmel_mci", id); |
@@ -1286,28 +1317,80 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | |||
1286 | ARRAY_SIZE(atmel_mci0_resource))) | 1317 | ARRAY_SIZE(atmel_mci0_resource))) |
1287 | goto fail; | 1318 | goto fail; |
1288 | 1319 | ||
1289 | if (!data) { | 1320 | if (data->dma_slave) |
1290 | data = &_data; | 1321 | dws = kmemdup(to_dw_dma_slave(data->dma_slave), |
1291 | memset(data, -1, sizeof(struct mci_platform_data)); | 1322 | sizeof(struct dw_dma_slave), GFP_KERNEL); |
1292 | data->detect_pin = GPIO_PIN_NONE; | 1323 | else |
1293 | data->wp_pin = GPIO_PIN_NONE; | 1324 | dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL); |
1294 | } | 1325 | |
1326 | dws->slave.dev = &pdev->dev; | ||
1327 | dws->slave.dma_dev = &dw_dmac0_device.dev; | ||
1328 | dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT; | ||
1329 | dws->cfg_hi = (DWC_CFGH_SRC_PER(0) | ||
1330 | | DWC_CFGH_DST_PER(1)); | ||
1331 | dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | ||
1332 | | DWC_CFGL_HS_SRC_POL); | ||
1333 | |||
1334 | data->dma_slave = &dws->slave; | ||
1295 | 1335 | ||
1296 | if (platform_device_add_data(pdev, data, | 1336 | if (platform_device_add_data(pdev, data, |
1297 | sizeof(struct mci_platform_data))) | 1337 | sizeof(struct mci_platform_data))) |
1298 | goto fail; | 1338 | goto fail; |
1299 | 1339 | ||
1300 | select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ | 1340 | /* CLK line is common to both slots */ |
1301 | select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ | 1341 | pioa_mask = 1 << 10; |
1302 | select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */ | ||
1303 | select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */ | ||
1304 | select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ | ||
1305 | select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ | ||
1306 | 1342 | ||
1307 | if (gpio_is_valid(data->detect_pin)) | 1343 | switch (data->slot[0].bus_width) { |
1308 | at32_select_gpio(data->detect_pin, 0); | 1344 | case 4: |
1309 | if (gpio_is_valid(data->wp_pin)) | 1345 | pioa_mask |= 1 << 13; /* DATA1 */ |
1310 | at32_select_gpio(data->wp_pin, 0); | 1346 | pioa_mask |= 1 << 14; /* DATA2 */ |
1347 | pioa_mask |= 1 << 15; /* DATA3 */ | ||
1348 | /* fall through */ | ||
1349 | case 1: | ||
1350 | pioa_mask |= 1 << 11; /* CMD */ | ||
1351 | pioa_mask |= 1 << 12; /* DATA0 */ | ||
1352 | |||
1353 | if (gpio_is_valid(data->slot[0].detect_pin)) | ||
1354 | at32_select_gpio(data->slot[0].detect_pin, 0); | ||
1355 | if (gpio_is_valid(data->slot[0].wp_pin)) | ||
1356 | at32_select_gpio(data->slot[0].wp_pin, 0); | ||
1357 | break; | ||
1358 | case 0: | ||
1359 | /* Slot is unused */ | ||
1360 | break; | ||
1361 | default: | ||
1362 | goto fail; | ||
1363 | } | ||
1364 | |||
1365 | select_peripheral(PIOA, pioa_mask, PERIPH_A, 0); | ||
1366 | piob_mask = 0; | ||
1367 | |||
1368 | switch (data->slot[1].bus_width) { | ||
1369 | case 4: | ||
1370 | piob_mask |= 1 << 8; /* DATA1 */ | ||
1371 | piob_mask |= 1 << 9; /* DATA2 */ | ||
1372 | piob_mask |= 1 << 10; /* DATA3 */ | ||
1373 | /* fall through */ | ||
1374 | case 1: | ||
1375 | piob_mask |= 1 << 6; /* CMD */ | ||
1376 | piob_mask |= 1 << 7; /* DATA0 */ | ||
1377 | select_peripheral(PIOB, piob_mask, PERIPH_B, 0); | ||
1378 | |||
1379 | if (gpio_is_valid(data->slot[1].detect_pin)) | ||
1380 | at32_select_gpio(data->slot[1].detect_pin, 0); | ||
1381 | if (gpio_is_valid(data->slot[1].wp_pin)) | ||
1382 | at32_select_gpio(data->slot[1].wp_pin, 0); | ||
1383 | break; | ||
1384 | case 0: | ||
1385 | /* Slot is unused */ | ||
1386 | break; | ||
1387 | default: | ||
1388 | if (!data->slot[0].bus_width) | ||
1389 | goto fail; | ||
1390 | |||
1391 | data->slot[1].bus_width = 0; | ||
1392 | break; | ||
1393 | } | ||
1311 | 1394 | ||
1312 | atmel_mci0_pclk.dev = &pdev->dev; | 1395 | atmel_mci0_pclk.dev = &pdev->dev; |
1313 | 1396 | ||
@@ -1353,13 +1436,14 @@ static struct clk atmel_lcdfb0_pixclk = { | |||
1353 | struct platform_device *__init | 1436 | struct platform_device *__init |
1354 | at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, | 1437 | at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, |
1355 | unsigned long fbmem_start, unsigned long fbmem_len, | 1438 | unsigned long fbmem_start, unsigned long fbmem_len, |
1356 | unsigned int pin_config) | 1439 | u64 pin_mask) |
1357 | { | 1440 | { |
1358 | struct platform_device *pdev; | 1441 | struct platform_device *pdev; |
1359 | struct atmel_lcdfb_info *info; | 1442 | struct atmel_lcdfb_info *info; |
1360 | struct fb_monspecs *monspecs; | 1443 | struct fb_monspecs *monspecs; |
1361 | struct fb_videomode *modedb; | 1444 | struct fb_videomode *modedb; |
1362 | unsigned int modedb_size; | 1445 | unsigned int modedb_size; |
1446 | u32 portc_mask, portd_mask, porte_mask; | ||
1363 | 1447 | ||
1364 | /* | 1448 | /* |
1365 | * Do a deep copy of the fb data, monspecs and modedb. Make | 1449 | * Do a deep copy of the fb data, monspecs and modedb. Make |
@@ -1381,76 +1465,21 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, | |||
1381 | case 0: | 1465 | case 0: |
1382 | pdev = &atmel_lcdfb0_device; | 1466 | pdev = &atmel_lcdfb0_device; |
1383 | 1467 | ||
1384 | switch (pin_config) { | 1468 | if (pin_mask == 0ULL) |
1385 | case 0: | 1469 | /* Default to "full" lcdc control signals and 24bit */ |
1386 | select_peripheral(PC(19), PERIPH_A, 0); /* CC */ | 1470 | pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL; |
1387 | select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ | 1471 | |
1388 | select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ | 1472 | /* LCDC on port C */ |
1389 | select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ | 1473 | portc_mask = (pin_mask & 0xfff80000) >> 19; |
1390 | select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ | 1474 | select_peripheral(PIOC, portc_mask, PERIPH_A, 0); |
1391 | select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ | 1475 | |
1392 | select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ | 1476 | /* LCDC on port D */ |
1393 | select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ | 1477 | portd_mask = pin_mask & 0x0003ffff; |
1394 | select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ | 1478 | select_peripheral(PIOD, portd_mask, PERIPH_A, 0); |
1395 | select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ | 1479 | |
1396 | select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ | 1480 | /* LCDC on port E */ |
1397 | select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ | 1481 | porte_mask = (pin_mask >> 32) & 0x0007ffff; |
1398 | select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ | 1482 | select_peripheral(PIOE, porte_mask, PERIPH_B, 0); |
1399 | select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ | ||
1400 | select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ | ||
1401 | select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ | ||
1402 | select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ | ||
1403 | select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ | ||
1404 | select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ | ||
1405 | select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ | ||
1406 | select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ | ||
1407 | select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ | ||
1408 | select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ | ||
1409 | select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ | ||
1410 | select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ | ||
1411 | select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ | ||
1412 | select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ | ||
1413 | select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ | ||
1414 | select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ | ||
1415 | select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ | ||
1416 | select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ | ||
1417 | break; | ||
1418 | case 1: | ||
1419 | select_peripheral(PE(0), PERIPH_B, 0); /* CC */ | ||
1420 | select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ | ||
1421 | select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ | ||
1422 | select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ | ||
1423 | select_peripheral(PE(1), PERIPH_B, 0); /* DVAL */ | ||
1424 | select_peripheral(PE(2), PERIPH_B, 0); /* MODE */ | ||
1425 | select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ | ||
1426 | select_peripheral(PE(3), PERIPH_B, 0); /* DATA0 */ | ||
1427 | select_peripheral(PE(4), PERIPH_B, 0); /* DATA1 */ | ||
1428 | select_peripheral(PE(5), PERIPH_B, 0); /* DATA2 */ | ||
1429 | select_peripheral(PE(6), PERIPH_B, 0); /* DATA3 */ | ||
1430 | select_peripheral(PE(7), PERIPH_B, 0); /* DATA4 */ | ||
1431 | select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ | ||
1432 | select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ | ||
1433 | select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ | ||
1434 | select_peripheral(PE(8), PERIPH_B, 0); /* DATA8 */ | ||
1435 | select_peripheral(PE(9), PERIPH_B, 0); /* DATA9 */ | ||
1436 | select_peripheral(PE(10), PERIPH_B, 0); /* DATA10 */ | ||
1437 | select_peripheral(PE(11), PERIPH_B, 0); /* DATA11 */ | ||
1438 | select_peripheral(PE(12), PERIPH_B, 0); /* DATA12 */ | ||
1439 | select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ | ||
1440 | select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ | ||
1441 | select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ | ||
1442 | select_peripheral(PE(13), PERIPH_B, 0); /* DATA16 */ | ||
1443 | select_peripheral(PE(14), PERIPH_B, 0); /* DATA17 */ | ||
1444 | select_peripheral(PE(15), PERIPH_B, 0); /* DATA18 */ | ||
1445 | select_peripheral(PE(16), PERIPH_B, 0); /* DATA19 */ | ||
1446 | select_peripheral(PE(17), PERIPH_B, 0); /* DATA20 */ | ||
1447 | select_peripheral(PE(18), PERIPH_B, 0); /* DATA21 */ | ||
1448 | select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ | ||
1449 | select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ | ||
1450 | break; | ||
1451 | default: | ||
1452 | goto err_invalid_id; | ||
1453 | } | ||
1454 | 1483 | ||
1455 | clk_set_parent(&atmel_lcdfb0_pixclk, &pll0); | 1484 | clk_set_parent(&atmel_lcdfb0_pixclk, &pll0); |
1456 | clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0)); | 1485 | clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0)); |
@@ -1499,6 +1528,7 @@ static struct clk atmel_pwm0_mck = { | |||
1499 | struct platform_device *__init at32_add_device_pwm(u32 mask) | 1528 | struct platform_device *__init at32_add_device_pwm(u32 mask) |
1500 | { | 1529 | { |
1501 | struct platform_device *pdev; | 1530 | struct platform_device *pdev; |
1531 | u32 pin_mask; | ||
1502 | 1532 | ||
1503 | if (!mask) | 1533 | if (!mask) |
1504 | return NULL; | 1534 | return NULL; |
@@ -1514,14 +1544,21 @@ struct platform_device *__init at32_add_device_pwm(u32 mask) | |||
1514 | if (platform_device_add_data(pdev, &mask, sizeof(mask))) | 1544 | if (platform_device_add_data(pdev, &mask, sizeof(mask))) |
1515 | goto out_free_pdev; | 1545 | goto out_free_pdev; |
1516 | 1546 | ||
1547 | pin_mask = 0; | ||
1517 | if (mask & (1 << 0)) | 1548 | if (mask & (1 << 0)) |
1518 | select_peripheral(PA(28), PERIPH_A, 0); | 1549 | pin_mask |= (1 << 28); |
1519 | if (mask & (1 << 1)) | 1550 | if (mask & (1 << 1)) |
1520 | select_peripheral(PA(29), PERIPH_A, 0); | 1551 | pin_mask |= (1 << 29); |
1552 | if (pin_mask > 0) | ||
1553 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); | ||
1554 | |||
1555 | pin_mask = 0; | ||
1521 | if (mask & (1 << 2)) | 1556 | if (mask & (1 << 2)) |
1522 | select_peripheral(PA(21), PERIPH_B, 0); | 1557 | pin_mask |= (1 << 21); |
1523 | if (mask & (1 << 3)) | 1558 | if (mask & (1 << 3)) |
1524 | select_peripheral(PA(22), PERIPH_B, 0); | 1559 | pin_mask |= (1 << 22); |
1560 | if (pin_mask > 0) | ||
1561 | select_peripheral(PIOA, pin_mask, PERIPH_B, 0); | ||
1525 | 1562 | ||
1526 | atmel_pwm0_mck.dev = &pdev->dev; | 1563 | atmel_pwm0_mck.dev = &pdev->dev; |
1527 | 1564 | ||
@@ -1562,52 +1599,65 @@ struct platform_device *__init | |||
1562 | at32_add_device_ssc(unsigned int id, unsigned int flags) | 1599 | at32_add_device_ssc(unsigned int id, unsigned int flags) |
1563 | { | 1600 | { |
1564 | struct platform_device *pdev; | 1601 | struct platform_device *pdev; |
1602 | u32 pin_mask = 0; | ||
1565 | 1603 | ||
1566 | switch (id) { | 1604 | switch (id) { |
1567 | case 0: | 1605 | case 0: |
1568 | pdev = &ssc0_device; | 1606 | pdev = &ssc0_device; |
1569 | if (flags & ATMEL_SSC_RF) | 1607 | if (flags & ATMEL_SSC_RF) |
1570 | select_peripheral(PA(21), PERIPH_A, 0); /* RF */ | 1608 | pin_mask |= (1 << 21); /* RF */ |
1571 | if (flags & ATMEL_SSC_RK) | 1609 | if (flags & ATMEL_SSC_RK) |
1572 | select_peripheral(PA(22), PERIPH_A, 0); /* RK */ | 1610 | pin_mask |= (1 << 22); /* RK */ |
1573 | if (flags & ATMEL_SSC_TK) | 1611 | if (flags & ATMEL_SSC_TK) |
1574 | select_peripheral(PA(23), PERIPH_A, 0); /* TK */ | 1612 | pin_mask |= (1 << 23); /* TK */ |
1575 | if (flags & ATMEL_SSC_TF) | 1613 | if (flags & ATMEL_SSC_TF) |
1576 | select_peripheral(PA(24), PERIPH_A, 0); /* TF */ | 1614 | pin_mask |= (1 << 24); /* TF */ |
1577 | if (flags & ATMEL_SSC_TD) | 1615 | if (flags & ATMEL_SSC_TD) |
1578 | select_peripheral(PA(25), PERIPH_A, 0); /* TD */ | 1616 | pin_mask |= (1 << 25); /* TD */ |
1579 | if (flags & ATMEL_SSC_RD) | 1617 | if (flags & ATMEL_SSC_RD) |
1580 | select_peripheral(PA(26), PERIPH_A, 0); /* RD */ | 1618 | pin_mask |= (1 << 26); /* RD */ |
1619 | |||
1620 | if (pin_mask > 0) | ||
1621 | select_peripheral(PIOA, pin_mask, PERIPH_A, 0); | ||
1622 | |||
1581 | break; | 1623 | break; |
1582 | case 1: | 1624 | case 1: |
1583 | pdev = &ssc1_device; | 1625 | pdev = &ssc1_device; |
1584 | if (flags & ATMEL_SSC_RF) | 1626 | if (flags & ATMEL_SSC_RF) |
1585 | select_peripheral(PA(0), PERIPH_B, 0); /* RF */ | 1627 | pin_mask |= (1 << 0); /* RF */ |
1586 | if (flags & ATMEL_SSC_RK) | 1628 | if (flags & ATMEL_SSC_RK) |
1587 | select_peripheral(PA(1), PERIPH_B, 0); /* RK */ | 1629 | pin_mask |= (1 << 1); /* RK */ |
1588 | if (flags & ATMEL_SSC_TK) | 1630 | if (flags & ATMEL_SSC_TK) |
1589 | select_peripheral(PA(2), PERIPH_B, 0); /* TK */ | 1631 | pin_mask |= (1 << 2); /* TK */ |
1590 | if (flags & ATMEL_SSC_TF) | 1632 | if (flags & ATMEL_SSC_TF) |
1591 | select_peripheral(PA(3), PERIPH_B, 0); /* TF */ | 1633 | pin_mask |= (1 << 3); /* TF */ |
1592 | if (flags & ATMEL_SSC_TD) | 1634 | if (flags & ATMEL_SSC_TD) |
1593 | select_peripheral(PA(4), PERIPH_B, 0); /* TD */ | 1635 | pin_mask |= (1 << 4); /* TD */ |
1594 | if (flags & ATMEL_SSC_RD) | 1636 | if (flags & ATMEL_SSC_RD) |
1595 | select_peripheral(PA(5), PERIPH_B, 0); /* RD */ | 1637 | pin_mask |= (1 << 5); /* RD */ |
1638 | |||
1639 | if (pin_mask > 0) | ||
1640 | select_peripheral(PIOA, pin_mask, PERIPH_B, 0); | ||
1641 | |||
1596 | break; | 1642 | break; |
1597 | case 2: | 1643 | case 2: |
1598 | pdev = &ssc2_device; | 1644 | pdev = &ssc2_device; |
1599 | if (flags & ATMEL_SSC_TD) | 1645 | if (flags & ATMEL_SSC_TD) |
1600 | select_peripheral(PB(13), PERIPH_A, 0); /* TD */ | 1646 | pin_mask |= (1 << 13); /* TD */ |
1601 | if (flags & ATMEL_SSC_RD) | 1647 | if (flags & ATMEL_SSC_RD) |
1602 | select_peripheral(PB(14), PERIPH_A, 0); /* RD */ | 1648 | pin_mask |= (1 << 14); /* RD */ |
1603 | if (flags & ATMEL_SSC_TK) | 1649 | if (flags & ATMEL_SSC_TK) |
1604 | select_peripheral(PB(15), PERIPH_A, 0); /* TK */ | 1650 | pin_mask |= (1 << 15); /* TK */ |
1605 | if (flags & ATMEL_SSC_TF) | 1651 | if (flags & ATMEL_SSC_TF) |
1606 | select_peripheral(PB(16), PERIPH_A, 0); /* TF */ | 1652 | pin_mask |= (1 << 16); /* TF */ |
1607 | if (flags & ATMEL_SSC_RF) | 1653 | if (flags & ATMEL_SSC_RF) |
1608 | select_peripheral(PB(17), PERIPH_A, 0); /* RF */ | 1654 | pin_mask |= (1 << 17); /* RF */ |
1609 | if (flags & ATMEL_SSC_RK) | 1655 | if (flags & ATMEL_SSC_RK) |
1610 | select_peripheral(PB(18), PERIPH_A, 0); /* RK */ | 1656 | pin_mask |= (1 << 18); /* RK */ |
1657 | |||
1658 | if (pin_mask > 0) | ||
1659 | select_peripheral(PIOB, pin_mask, PERIPH_A, 0); | ||
1660 | |||
1611 | break; | 1661 | break; |
1612 | default: | 1662 | default: |
1613 | return NULL; | 1663 | return NULL; |
@@ -1745,14 +1795,15 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev, | |||
1745 | unsigned int cs, unsigned int extint) | 1795 | unsigned int cs, unsigned int extint) |
1746 | { | 1796 | { |
1747 | static unsigned int extint_pin_map[4] __initdata = { | 1797 | static unsigned int extint_pin_map[4] __initdata = { |
1748 | GPIO_PIN_PB(25), | 1798 | (1 << 25), |
1749 | GPIO_PIN_PB(26), | 1799 | (1 << 26), |
1750 | GPIO_PIN_PB(27), | 1800 | (1 << 27), |
1751 | GPIO_PIN_PB(28), | 1801 | (1 << 28), |
1752 | }; | 1802 | }; |
1753 | static bool common_pins_initialized __initdata = false; | 1803 | static bool common_pins_initialized __initdata = false; |
1754 | unsigned int extint_pin; | 1804 | unsigned int extint_pin; |
1755 | int ret; | 1805 | int ret; |
1806 | u32 pin_mask; | ||
1756 | 1807 | ||
1757 | if (extint >= ARRAY_SIZE(extint_pin_map)) | 1808 | if (extint >= ARRAY_SIZE(extint_pin_map)) |
1758 | return -EINVAL; | 1809 | return -EINVAL; |
@@ -1766,7 +1817,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev, | |||
1766 | if (ret) | 1817 | if (ret) |
1767 | return ret; | 1818 | return ret; |
1768 | 1819 | ||
1769 | select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */ | 1820 | /* NCS4 -> OE_N */ |
1821 | select_peripheral(PIOE, (1 << 21), PERIPH_A, 0); | ||
1770 | hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE); | 1822 | hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE); |
1771 | break; | 1823 | break; |
1772 | case 5: | 1824 | case 5: |
@@ -1776,7 +1828,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev, | |||
1776 | if (ret) | 1828 | if (ret) |
1777 | return ret; | 1829 | return ret; |
1778 | 1830 | ||
1779 | select_peripheral(PE(22), PERIPH_A, 0); /* NCS5 -> OE_N */ | 1831 | /* NCS5 -> OE_N */ |
1832 | select_peripheral(PIOE, (1 << 22), PERIPH_A, 0); | ||
1780 | hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE); | 1833 | hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE); |
1781 | break; | 1834 | break; |
1782 | default: | 1835 | default: |
@@ -1784,14 +1837,17 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev, | |||
1784 | } | 1837 | } |
1785 | 1838 | ||
1786 | if (!common_pins_initialized) { | 1839 | if (!common_pins_initialized) { |
1787 | select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */ | 1840 | pin_mask = (1 << 19); /* CFCE1 -> CS0_N */ |
1788 | select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */ | 1841 | pin_mask |= (1 << 20); /* CFCE2 -> CS1_N */ |
1789 | select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */ | 1842 | pin_mask |= (1 << 23); /* CFRNW -> DIR */ |
1790 | select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */ | 1843 | pin_mask |= (1 << 24); /* NWAIT <- IORDY */ |
1844 | |||
1845 | select_peripheral(PIOE, pin_mask, PERIPH_A, 0); | ||
1846 | |||
1791 | common_pins_initialized = true; | 1847 | common_pins_initialized = true; |
1792 | } | 1848 | } |
1793 | 1849 | ||
1794 | at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); | 1850 | select_peripheral(PIOB, extint_pin, PERIPH_A, AT32_GPIOF_DEGLITCH); |
1795 | 1851 | ||
1796 | pdev->resource[1].start = EIM_IRQ_BASE + extint; | 1852 | pdev->resource[1].start = EIM_IRQ_BASE + extint; |
1797 | pdev->resource[1].end = pdev->resource[1].start; | 1853 | pdev->resource[1].end = pdev->resource[1].start; |
@@ -1930,6 +1986,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) | |||
1930 | { | 1986 | { |
1931 | struct platform_device *pdev; | 1987 | struct platform_device *pdev; |
1932 | struct ac97c_platform_data _data; | 1988 | struct ac97c_platform_data _data; |
1989 | u32 pin_mask; | ||
1933 | 1990 | ||
1934 | if (id != 0) | 1991 | if (id != 0) |
1935 | return NULL; | 1992 | return NULL; |
@@ -1956,10 +2013,10 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) | |||
1956 | sizeof(struct ac97c_platform_data))) | 2013 | sizeof(struct ac97c_platform_data))) |
1957 | goto fail; | 2014 | goto fail; |
1958 | 2015 | ||
1959 | select_peripheral(PB(20), PERIPH_B, 0); /* SDO */ | 2016 | pin_mask = (1 << 20) | (1 << 21); /* SDO & SYNC */ |
1960 | select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */ | 2017 | pin_mask |= (1 << 22) | (1 << 23); /* SCLK & SDI */ |
1961 | select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */ | 2018 | |
1962 | select_peripheral(PB(23), PERIPH_B, 0); /* SDI */ | 2019 | select_peripheral(PIOB, pin_mask, PERIPH_B, 0); |
1963 | 2020 | ||
1964 | /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ | 2021 | /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ |
1965 | if (data->reset_pin != GPIO_PIN_NONE) | 2022 | if (data->reset_pin != GPIO_PIN_NONE) |
@@ -2001,6 +2058,7 @@ static struct clk abdac0_sample_clk = { | |||
2001 | struct platform_device *__init at32_add_device_abdac(unsigned int id) | 2058 | struct platform_device *__init at32_add_device_abdac(unsigned int id) |
2002 | { | 2059 | { |
2003 | struct platform_device *pdev; | 2060 | struct platform_device *pdev; |
2061 | u32 pin_mask; | ||
2004 | 2062 | ||
2005 | if (id != 0) | 2063 | if (id != 0) |
2006 | return NULL; | 2064 | return NULL; |
@@ -2013,10 +2071,10 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id) | |||
2013 | ARRAY_SIZE(abdac0_resource))) | 2071 | ARRAY_SIZE(abdac0_resource))) |
2014 | goto err_add_resources; | 2072 | goto err_add_resources; |
2015 | 2073 | ||
2016 | select_peripheral(PB(20), PERIPH_A, 0); /* DATA1 */ | 2074 | pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */ |
2017 | select_peripheral(PB(21), PERIPH_A, 0); /* DATA0 */ | 2075 | pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */ |
2018 | select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1 */ | 2076 | |
2019 | select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0 */ | 2077 | select_peripheral(PIOB, pin_mask, PERIPH_A, 0); |
2020 | 2078 | ||
2021 | abdac0_pclk.dev = &pdev->dev; | 2079 | abdac0_pclk.dev = &pdev->dev; |
2022 | abdac0_sample_clk.dev = &pdev->dev; | 2080 | abdac0_sample_clk.dev = &pdev->dev; |
@@ -2073,7 +2131,7 @@ static struct clk gclk4 = { | |||
2073 | .index = 4, | 2131 | .index = 4, |
2074 | }; | 2132 | }; |
2075 | 2133 | ||
2076 | struct clk *at32_clock_list[] = { | 2134 | static __initdata struct clk *init_clocks[] = { |
2077 | &osc32k, | 2135 | &osc32k, |
2078 | &osc0, | 2136 | &osc0, |
2079 | &osc1, | 2137 | &osc1, |
@@ -2137,7 +2195,6 @@ struct clk *at32_clock_list[] = { | |||
2137 | &gclk3, | 2195 | &gclk3, |
2138 | &gclk4, | 2196 | &gclk4, |
2139 | }; | 2197 | }; |
2140 | unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); | ||
2141 | 2198 | ||
2142 | void __init setup_platform(void) | 2199 | void __init setup_platform(void) |
2143 | { | 2200 | { |
@@ -2168,14 +2225,19 @@ void __init setup_platform(void) | |||
2168 | genclk_init_parent(&abdac0_sample_clk); | 2225 | genclk_init_parent(&abdac0_sample_clk); |
2169 | 2226 | ||
2170 | /* | 2227 | /* |
2171 | * Turn on all clocks that have at least one user already, and | 2228 | * Build initial dynamic clock list by registering all clocks |
2172 | * turn off everything else. We only do this for module | 2229 | * from the array. |
2173 | * clocks, and even though it isn't particularly pretty to | 2230 | * At the same time, turn on all clocks that have at least one |
2174 | * check the address of the mode function, it should do the | 2231 | * user already, and turn off everything else. We only do this |
2175 | * trick... | 2232 | * for module clocks, and even though it isn't particularly |
2233 | * pretty to check the address of the mode function, it should | ||
2234 | * do the trick... | ||
2176 | */ | 2235 | */ |
2177 | for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) { | 2236 | for (i = 0; i < ARRAY_SIZE(init_clocks); i++) { |
2178 | struct clk *clk = at32_clock_list[i]; | 2237 | struct clk *clk = init_clocks[i]; |
2238 | |||
2239 | /* first, register clock */ | ||
2240 | at32_clk_register(clk); | ||
2179 | 2241 | ||
2180 | if (clk->users == 0) | 2242 | if (clk->users == 0) |
2181 | continue; | 2243 | continue; |
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c index 6c27ddac5adf..138a00a2a2d0 100644 --- a/arch/avr32/mach-at32ap/clock.c +++ b/arch/avr32/mach-at32ap/clock.c | |||
@@ -15,24 +15,40 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/list.h> | ||
18 | 19 | ||
19 | #include <mach/chip.h> | 20 | #include <mach/chip.h> |
20 | 21 | ||
21 | #include "clock.h" | 22 | #include "clock.h" |
22 | 23 | ||
24 | /* at32 clock list */ | ||
25 | static LIST_HEAD(at32_clock_list); | ||
26 | |||
23 | static DEFINE_SPINLOCK(clk_lock); | 27 | static DEFINE_SPINLOCK(clk_lock); |
28 | static DEFINE_SPINLOCK(clk_list_lock); | ||
29 | |||
30 | void at32_clk_register(struct clk *clk) | ||
31 | { | ||
32 | spin_lock(&clk_list_lock); | ||
33 | /* add the new item to the end of the list */ | ||
34 | list_add_tail(&clk->list, &at32_clock_list); | ||
35 | spin_unlock(&clk_list_lock); | ||
36 | } | ||
24 | 37 | ||
25 | struct clk *clk_get(struct device *dev, const char *id) | 38 | struct clk *clk_get(struct device *dev, const char *id) |
26 | { | 39 | { |
27 | int i; | 40 | struct clk *clk; |
28 | 41 | ||
29 | for (i = 0; i < at32_nr_clocks; i++) { | 42 | spin_lock(&clk_list_lock); |
30 | struct clk *clk = at32_clock_list[i]; | ||
31 | 43 | ||
32 | if (clk->dev == dev && strcmp(id, clk->name) == 0) | 44 | list_for_each_entry(clk, &at32_clock_list, list) { |
45 | if (clk->dev == dev && strcmp(id, clk->name) == 0) { | ||
46 | spin_unlock(&clk_list_lock); | ||
33 | return clk; | 47 | return clk; |
48 | } | ||
34 | } | 49 | } |
35 | 50 | ||
51 | spin_unlock(&clk_list_lock); | ||
36 | return ERR_PTR(-ENOENT); | 52 | return ERR_PTR(-ENOENT); |
37 | } | 53 | } |
38 | EXPORT_SYMBOL(clk_get); | 54 | EXPORT_SYMBOL(clk_get); |
@@ -203,8 +219,8 @@ dump_clock(struct clk *parent, struct clkinf *r) | |||
203 | 219 | ||
204 | /* cost of this scan is small, but not linear... */ | 220 | /* cost of this scan is small, but not linear... */ |
205 | r->nest = nest + NEST_DELTA; | 221 | r->nest = nest + NEST_DELTA; |
206 | for (i = 3; i < at32_nr_clocks; i++) { | 222 | |
207 | clk = at32_clock_list[i]; | 223 | list_for_each_entry(clk, &at32_clock_list, list) { |
208 | if (clk->parent == parent) | 224 | if (clk->parent == parent) |
209 | dump_clock(clk, r); | 225 | dump_clock(clk, r); |
210 | } | 226 | } |
@@ -215,6 +231,7 @@ static int clk_show(struct seq_file *s, void *unused) | |||
215 | { | 231 | { |
216 | struct clkinf r; | 232 | struct clkinf r; |
217 | int i; | 233 | int i; |
234 | struct clk *clk; | ||
218 | 235 | ||
219 | /* show all the power manager registers */ | 236 | /* show all the power manager registers */ |
220 | seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL)); | 237 | seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL)); |
@@ -234,14 +251,25 @@ static int clk_show(struct seq_file *s, void *unused) | |||
234 | 251 | ||
235 | seq_printf(s, "\n"); | 252 | seq_printf(s, "\n"); |
236 | 253 | ||
237 | /* show clock tree as derived from the three oscillators | ||
238 | * we "know" are at the head of the list | ||
239 | */ | ||
240 | r.s = s; | 254 | r.s = s; |
241 | r.nest = 0; | 255 | r.nest = 0; |
242 | dump_clock(at32_clock_list[0], &r); | 256 | /* protected from changes on the list while dumping */ |
243 | dump_clock(at32_clock_list[1], &r); | 257 | spin_lock(&clk_list_lock); |
244 | dump_clock(at32_clock_list[2], &r); | 258 | |
259 | /* show clock tree as derived from the three oscillators */ | ||
260 | clk = clk_get(NULL, "osc32k"); | ||
261 | dump_clock(clk, &r); | ||
262 | clk_put(clk); | ||
263 | |||
264 | clk = clk_get(NULL, "osc0"); | ||
265 | dump_clock(clk, &r); | ||
266 | clk_put(clk); | ||
267 | |||
268 | clk = clk_get(NULL, "osc1"); | ||
269 | dump_clock(clk, &r); | ||
270 | clk_put(clk); | ||
271 | |||
272 | spin_unlock(&clk_list_lock); | ||
245 | 273 | ||
246 | return 0; | 274 | return 0; |
247 | } | 275 | } |
diff --git a/arch/avr32/mach-at32ap/clock.h b/arch/avr32/mach-at32ap/clock.h index bb8e1f295835..623bf0e9a1e7 100644 --- a/arch/avr32/mach-at32ap/clock.h +++ b/arch/avr32/mach-at32ap/clock.h | |||
@@ -12,8 +12,13 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/list.h> | ||
16 | |||
17 | |||
18 | void at32_clk_register(struct clk *clk); | ||
15 | 19 | ||
16 | struct clk { | 20 | struct clk { |
21 | struct list_head list; /* linking element */ | ||
17 | const char *name; /* Clock name/function */ | 22 | const char *name; /* Clock name/function */ |
18 | struct device *dev; /* Device the clock is used by */ | 23 | struct device *dev; /* Device the clock is used by */ |
19 | struct clk *parent; /* Parent clock, if any */ | 24 | struct clk *parent; /* Parent clock, if any */ |
@@ -25,6 +30,3 @@ struct clk { | |||
25 | u16 users; /* Enabled if non-zero */ | 30 | u16 users; /* Enabled if non-zero */ |
26 | u16 index; /* Sibling index */ | 31 | u16 index; /* Sibling index */ |
27 | }; | 32 | }; |
28 | |||
29 | extern struct clk *at32_clock_list[]; | ||
30 | extern unsigned int at32_nr_clocks; | ||
diff --git a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h index 1e9852d65cca..a77d372f6f3e 100644 --- a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h +++ b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h | |||
@@ -83,4 +83,132 @@ | |||
83 | #define HMATRIX_BASE 0xfff00800 | 83 | #define HMATRIX_BASE 0xfff00800 |
84 | #define SDRAMC_BASE 0xfff03800 | 84 | #define SDRAMC_BASE 0xfff03800 |
85 | 85 | ||
86 | /* LCDC on port C */ | ||
87 | #define ATMEL_LCDC_PC_CC (1ULL << 19) | ||
88 | #define ATMEL_LCDC_PC_HSYNC (1ULL << 20) | ||
89 | #define ATMEL_LCDC_PC_PCLK (1ULL << 21) | ||
90 | #define ATMEL_LCDC_PC_VSYNC (1ULL << 22) | ||
91 | #define ATMEL_LCDC_PC_DVAL (1ULL << 23) | ||
92 | #define ATMEL_LCDC_PC_MODE (1ULL << 24) | ||
93 | #define ATMEL_LCDC_PC_PWR (1ULL << 25) | ||
94 | #define ATMEL_LCDC_PC_DATA0 (1ULL << 26) | ||
95 | #define ATMEL_LCDC_PC_DATA1 (1ULL << 27) | ||
96 | #define ATMEL_LCDC_PC_DATA2 (1ULL << 28) | ||
97 | #define ATMEL_LCDC_PC_DATA3 (1ULL << 29) | ||
98 | #define ATMEL_LCDC_PC_DATA4 (1ULL << 30) | ||
99 | #define ATMEL_LCDC_PC_DATA5 (1ULL << 31) | ||
100 | |||
101 | /* LCDC on port D */ | ||
102 | #define ATMEL_LCDC_PD_DATA6 (1ULL << 0) | ||
103 | #define ATMEL_LCDC_PD_DATA7 (1ULL << 1) | ||
104 | #define ATMEL_LCDC_PD_DATA8 (1ULL << 2) | ||
105 | #define ATMEL_LCDC_PD_DATA9 (1ULL << 3) | ||
106 | #define ATMEL_LCDC_PD_DATA10 (1ULL << 4) | ||
107 | #define ATMEL_LCDC_PD_DATA11 (1ULL << 5) | ||
108 | #define ATMEL_LCDC_PD_DATA12 (1ULL << 6) | ||
109 | #define ATMEL_LCDC_PD_DATA13 (1ULL << 7) | ||
110 | #define ATMEL_LCDC_PD_DATA14 (1ULL << 8) | ||
111 | #define ATMEL_LCDC_PD_DATA15 (1ULL << 9) | ||
112 | #define ATMEL_LCDC_PD_DATA16 (1ULL << 10) | ||
113 | #define ATMEL_LCDC_PD_DATA17 (1ULL << 11) | ||
114 | #define ATMEL_LCDC_PD_DATA18 (1ULL << 12) | ||
115 | #define ATMEL_LCDC_PD_DATA19 (1ULL << 13) | ||
116 | #define ATMEL_LCDC_PD_DATA20 (1ULL << 14) | ||
117 | #define ATMEL_LCDC_PD_DATA21 (1ULL << 15) | ||
118 | #define ATMEL_LCDC_PD_DATA22 (1ULL << 16) | ||
119 | #define ATMEL_LCDC_PD_DATA23 (1ULL << 17) | ||
120 | |||
121 | /* LCDC on port E */ | ||
122 | #define ATMEL_LCDC_PE_CC (1ULL << (32 + 0)) | ||
123 | #define ATMEL_LCDC_PE_DVAL (1ULL << (32 + 1)) | ||
124 | #define ATMEL_LCDC_PE_MODE (1ULL << (32 + 2)) | ||
125 | #define ATMEL_LCDC_PE_DATA0 (1ULL << (32 + 3)) | ||
126 | #define ATMEL_LCDC_PE_DATA1 (1ULL << (32 + 4)) | ||
127 | #define ATMEL_LCDC_PE_DATA2 (1ULL << (32 + 5)) | ||
128 | #define ATMEL_LCDC_PE_DATA3 (1ULL << (32 + 6)) | ||
129 | #define ATMEL_LCDC_PE_DATA4 (1ULL << (32 + 7)) | ||
130 | #define ATMEL_LCDC_PE_DATA8 (1ULL << (32 + 8)) | ||
131 | #define ATMEL_LCDC_PE_DATA9 (1ULL << (32 + 9)) | ||
132 | #define ATMEL_LCDC_PE_DATA10 (1ULL << (32 + 10)) | ||
133 | #define ATMEL_LCDC_PE_DATA11 (1ULL << (32 + 11)) | ||
134 | #define ATMEL_LCDC_PE_DATA12 (1ULL << (32 + 12)) | ||
135 | #define ATMEL_LCDC_PE_DATA16 (1ULL << (32 + 13)) | ||
136 | #define ATMEL_LCDC_PE_DATA17 (1ULL << (32 + 14)) | ||
137 | #define ATMEL_LCDC_PE_DATA18 (1ULL << (32 + 15)) | ||
138 | #define ATMEL_LCDC_PE_DATA19 (1ULL << (32 + 16)) | ||
139 | #define ATMEL_LCDC_PE_DATA20 (1ULL << (32 + 17)) | ||
140 | #define ATMEL_LCDC_PE_DATA21 (1ULL << (32 + 18)) | ||
141 | |||
142 | |||
143 | #define ATMEL_LCDC(PORT, PIN) (ATMEL_LCDC_##PORT##_##PIN) | ||
144 | |||
145 | |||
146 | #define ATMEL_LCDC_PRI_24B_DATA ( \ | ||
147 | ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \ | ||
148 | ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \ | ||
149 | ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \ | ||
150 | ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ | ||
151 | ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \ | ||
152 | ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \ | ||
153 | ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \ | ||
154 | ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ | ||
155 | ATMEL_LCDC(PD, DATA16) | ATMEL_LCDC(PD, DATA17) | \ | ||
156 | ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \ | ||
157 | ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \ | ||
158 | ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) | ||
159 | |||
160 | #define ATMEL_LCDC_ALT_24B_DATA ( \ | ||
161 | ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \ | ||
162 | ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \ | ||
163 | ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \ | ||
164 | ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ | ||
165 | ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \ | ||
166 | ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \ | ||
167 | ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \ | ||
168 | ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ | ||
169 | ATMEL_LCDC(PE, DATA16) | ATMEL_LCDC(PE, DATA17) | \ | ||
170 | ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \ | ||
171 | ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \ | ||
172 | ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) | ||
173 | |||
174 | #define ATMEL_LCDC_PRI_15B_DATA ( \ | ||
175 | ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \ | ||
176 | ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \ | ||
177 | ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \ | ||
178 | ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \ | ||
179 | ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \ | ||
180 | ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) | \ | ||
181 | ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) | \ | ||
182 | ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20)) | ||
183 | |||
184 | #define ATMEL_LCDC_ALT_15B_DATA ( \ | ||
185 | ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \ | ||
186 | ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \ | ||
187 | ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \ | ||
188 | ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \ | ||
189 | ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \ | ||
190 | ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) | \ | ||
191 | ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) | \ | ||
192 | ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20)) | ||
193 | |||
194 | #define ATMEL_LCDC_PRI_CONTROL ( \ | ||
195 | ATMEL_LCDC(PC, CC) | ATMEL_LCDC(PC, DVAL) | \ | ||
196 | ATMEL_LCDC(PC, MODE) | ATMEL_LCDC(PC, PWR)) | ||
197 | |||
198 | #define ATMEL_LCDC_ALT_CONTROL ( \ | ||
199 | ATMEL_LCDC(PE, CC) | ATMEL_LCDC(PE, DVAL) | \ | ||
200 | ATMEL_LCDC(PE, MODE) | ATMEL_LCDC(PC, PWR)) | ||
201 | |||
202 | #define ATMEL_LCDC_CONTROL ( \ | ||
203 | ATMEL_LCDC(PC, HSYNC) | ATMEL_LCDC(PC, VSYNC) | \ | ||
204 | ATMEL_LCDC(PC, PCLK)) | ||
205 | |||
206 | #define ATMEL_LCDC_PRI_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_24B_DATA) | ||
207 | |||
208 | #define ATMEL_LCDC_ALT_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA) | ||
209 | |||
210 | #define ATMEL_LCDC_PRI_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA) | ||
211 | |||
212 | #define ATMEL_LCDC_ALT_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA) | ||
213 | |||
86 | #endif /* __ASM_ARCH_AT32AP700X_H__ */ | 214 | #endif /* __ASM_ARCH_AT32AP700X_H__ */ |
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index e60e9076544d..c48386d66bc3 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h | |||
@@ -43,7 +43,7 @@ struct atmel_lcdfb_info; | |||
43 | struct platform_device * | 43 | struct platform_device * |
44 | at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, | 44 | at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, |
45 | unsigned long fbmem_start, unsigned long fbmem_len, | 45 | unsigned long fbmem_start, unsigned long fbmem_len, |
46 | unsigned int pin_config); | 46 | u64 pin_mask); |
47 | 47 | ||
48 | struct usba_platform_data; | 48 | struct usba_platform_data; |
49 | struct platform_device * | 49 | struct platform_device * |
diff --git a/arch/avr32/mach-at32ap/include/mach/io.h b/arch/avr32/mach-at32ap/include/mach/io.h index 4ec6abc68ea3..22ea79b74052 100644 --- a/arch/avr32/mach-at32ap/include/mach/io.h +++ b/arch/avr32/mach-at32ap/include/mach/io.h | |||
@@ -1,8 +1,7 @@ | |||
1 | #ifndef __ASM_AVR32_ARCH_AT32AP_IO_H | 1 | #ifndef __ASM_AVR32_ARCH_AT32AP_IO_H |
2 | #define __ASM_AVR32_ARCH_AT32AP_IO_H | 2 | #define __ASM_AVR32_ARCH_AT32AP_IO_H |
3 | 3 | ||
4 | /* For "bizarre" halfword swapping */ | 4 | #include <linux/swab.h> |
5 | #include <linux/byteorder/swabb.h> | ||
6 | 5 | ||
7 | #if defined(CONFIG_AP700X_32_BIT_SMC) | 6 | #if defined(CONFIG_AP700X_32_BIT_SMC) |
8 | # define __swizzle_addr_b(addr) (addr ^ 3UL) | 7 | # define __swizzle_addr_b(addr) (addr ^ 3UL) |
diff --git a/arch/avr32/mach-at32ap/include/mach/portmux.h b/arch/avr32/mach-at32ap/include/mach/portmux.h index b1abe6b4e4ef..21c79373b53f 100644 --- a/arch/avr32/mach-at32ap/include/mach/portmux.h +++ b/arch/avr32/mach-at32ap/include/mach/portmux.h | |||
@@ -21,9 +21,10 @@ | |||
21 | #define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */ | 21 | #define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */ |
22 | #define AT32_GPIOF_MULTIDRV 0x00000010 /* Enable multidriver option */ | 22 | #define AT32_GPIOF_MULTIDRV 0x00000010 /* Enable multidriver option */ |
23 | 23 | ||
24 | void at32_select_periph(unsigned int pin, unsigned int periph, | 24 | void at32_select_periph(unsigned int port, unsigned int pin, |
25 | unsigned long flags); | 25 | unsigned int periph, unsigned long flags); |
26 | void at32_select_gpio(unsigned int pin, unsigned long flags); | 26 | void at32_select_gpio(unsigned int pin, unsigned long flags); |
27 | void at32_deselect_pin(unsigned int pin); | ||
27 | void at32_reserve_pin(unsigned int pin); | 28 | void at32_reserve_pin(unsigned int pin); |
28 | 29 | ||
29 | #endif /* __ASM_ARCH_PORTMUX_H__ */ | 30 | #endif /* __ASM_ARCH_PORTMUX_H__ */ |
diff --git a/arch/avr32/mach-at32ap/pdc.c b/arch/avr32/mach-at32ap/pdc.c index 1040bda4fda7..61ab15aae970 100644 --- a/arch/avr32/mach-at32ap/pdc.c +++ b/arch/avr32/mach-at32ap/pdc.c | |||
@@ -35,7 +35,6 @@ static int __init pdc_probe(struct platform_device *pdev) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | static struct platform_driver pdc_driver = { | 37 | static struct platform_driver pdc_driver = { |
38 | .probe = pdc_probe, | ||
39 | .driver = { | 38 | .driver = { |
40 | .name = "pdc", | 39 | .name = "pdc", |
41 | }, | 40 | }, |
@@ -43,6 +42,6 @@ static struct platform_driver pdc_driver = { | |||
43 | 42 | ||
44 | static int __init pdc_init(void) | 43 | static int __init pdc_init(void) |
45 | { | 44 | { |
46 | return platform_driver_register(&pdc_driver); | 45 | return platform_driver_probe(&pdc_driver, pdc_probe); |
47 | } | 46 | } |
48 | arch_initcall(pdc_init); | 47 | arch_initcall(pdc_init); |
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 405ee6bad4ce..ed81a8bcb22d 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c | |||
@@ -50,35 +50,48 @@ static struct pio_device *gpio_to_pio(unsigned int gpio) | |||
50 | } | 50 | } |
51 | 51 | ||
52 | /* Pin multiplexing API */ | 52 | /* Pin multiplexing API */ |
53 | static DEFINE_SPINLOCK(pio_lock); | ||
53 | 54 | ||
54 | void __init at32_select_periph(unsigned int pin, unsigned int periph, | 55 | void __init at32_select_periph(unsigned int port, u32 pin_mask, |
55 | unsigned long flags) | 56 | unsigned int periph, unsigned long flags) |
56 | { | 57 | { |
57 | struct pio_device *pio; | 58 | struct pio_device *pio; |
58 | unsigned int pin_index = pin & 0x1f; | ||
59 | u32 mask = 1 << pin_index; | ||
60 | 59 | ||
61 | pio = gpio_to_pio(pin); | 60 | /* assign and verify pio */ |
61 | pio = gpio_to_pio(port); | ||
62 | if (unlikely(!pio)) { | 62 | if (unlikely(!pio)) { |
63 | printk("pio: invalid pin %u\n", pin); | 63 | printk(KERN_WARNING "pio: invalid port %u\n", port); |
64 | goto fail; | 64 | goto fail; |
65 | } | 65 | } |
66 | 66 | ||
67 | if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask) | 67 | /* Test if any of the requested pins is already muxed */ |
68 | || gpiochip_is_requested(&pio->chip, pin_index))) { | 68 | spin_lock(&pio_lock); |
69 | printk("%s: pin %u is busy\n", pio->name, pin_index); | 69 | if (unlikely(pio->pinmux_mask & pin_mask)) { |
70 | printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n", | ||
71 | pio->name, pin_mask, pio->pinmux_mask & pin_mask); | ||
72 | spin_unlock(&pio_lock); | ||
70 | goto fail; | 73 | goto fail; |
71 | } | 74 | } |
72 | 75 | ||
73 | pio_writel(pio, PUER, mask); | 76 | pio->pinmux_mask |= pin_mask; |
77 | |||
78 | /* enable pull ups */ | ||
79 | pio_writel(pio, PUER, pin_mask); | ||
80 | |||
81 | /* select either peripheral A or B */ | ||
74 | if (periph) | 82 | if (periph) |
75 | pio_writel(pio, BSR, mask); | 83 | pio_writel(pio, BSR, pin_mask); |
76 | else | 84 | else |
77 | pio_writel(pio, ASR, mask); | 85 | pio_writel(pio, ASR, pin_mask); |
86 | |||
87 | /* enable peripheral control */ | ||
88 | pio_writel(pio, PDR, pin_mask); | ||
78 | 89 | ||
79 | pio_writel(pio, PDR, mask); | 90 | /* Disable pull ups if not requested. */ |
80 | if (!(flags & AT32_GPIOF_PULLUP)) | 91 | if (!(flags & AT32_GPIOF_PULLUP)) |
81 | pio_writel(pio, PUDR, mask); | 92 | pio_writel(pio, PUDR, pin_mask); |
93 | |||
94 | spin_unlock(&pio_lock); | ||
82 | 95 | ||
83 | return; | 96 | return; |
84 | 97 | ||
@@ -134,6 +147,25 @@ fail: | |||
134 | dump_stack(); | 147 | dump_stack(); |
135 | } | 148 | } |
136 | 149 | ||
150 | /* | ||
151 | * Undo a previous pin reservation. Will not affect the hardware | ||
152 | * configuration. | ||
153 | */ | ||
154 | void at32_deselect_pin(unsigned int pin) | ||
155 | { | ||
156 | struct pio_device *pio; | ||
157 | unsigned int pin_index = pin & 0x1f; | ||
158 | |||
159 | pio = gpio_to_pio(pin); | ||
160 | if (unlikely(!pio)) { | ||
161 | printk("pio: invalid pin %u\n", pin); | ||
162 | dump_stack(); | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | clear_bit(pin_index, &pio->pinmux_mask); | ||
167 | } | ||
168 | |||
137 | /* Reserve a pin, preventing anyone else from changing its configuration. */ | 169 | /* Reserve a pin, preventing anyone else from changing its configuration. */ |
138 | void __init at32_reserve_pin(unsigned int pin) | 170 | void __init at32_reserve_pin(unsigned int pin) |
139 | { | 171 | { |
@@ -382,7 +414,6 @@ static int __init pio_probe(struct platform_device *pdev) | |||
382 | } | 414 | } |
383 | 415 | ||
384 | static struct platform_driver pio_driver = { | 416 | static struct platform_driver pio_driver = { |
385 | .probe = pio_probe, | ||
386 | .driver = { | 417 | .driver = { |
387 | .name = "pio", | 418 | .name = "pio", |
388 | }, | 419 | }, |
@@ -390,7 +421,7 @@ static struct platform_driver pio_driver = { | |||
390 | 421 | ||
391 | static int __init pio_init(void) | 422 | static int __init pio_init(void) |
392 | { | 423 | { |
393 | return platform_driver_register(&pio_driver); | 424 | return platform_driver_probe(&pio_driver, pio_probe); |
394 | } | 425 | } |
395 | postcore_initcall(pio_init); | 426 | postcore_initcall(pio_init); |
396 | 427 | ||
diff --git a/arch/avr32/mach-at32ap/pm-at32ap700x.S b/arch/avr32/mach-at32ap/pm-at32ap700x.S index 5be4de65b209..17503b0ed6c9 100644 --- a/arch/avr32/mach-at32ap/pm-at32ap700x.S +++ b/arch/avr32/mach-at32ap/pm-at32ap700x.S | |||
@@ -134,7 +134,7 @@ pm_standby: | |||
134 | mov r11, SDRAMC_LPR_LPCB_SELF_RFR | 134 | mov r11, SDRAMC_LPR_LPCB_SELF_RFR |
135 | bfins r10, r11, 0, 2 /* LPCB <- self Refresh */ | 135 | bfins r10, r11, 0, 2 /* LPCB <- self Refresh */ |
136 | sync 0 /* flush write buffer */ | 136 | sync 0 /* flush write buffer */ |
137 | st.w r12[SDRAMC_LPR], r11 /* put SDRAM in self-refresh mode */ | 137 | st.w r12[SDRAMC_LPR], r10 /* put SDRAM in self-refresh mode */ |
138 | ld.w r11, r12[SDRAMC_LPR] | 138 | ld.w r11, r12[SDRAMC_LPR] |
139 | unmask_interrupts | 139 | unmask_interrupts |
140 | sleep CPU_SLEEP_FROZEN | 140 | sleep CPU_SLEEP_FROZEN |
diff --git a/arch/avr32/oprofile/Makefile b/arch/avr32/oprofile/Makefile index 1fe81c3c1e86..e0eb520e0287 100644 --- a/arch/avr32/oprofile/Makefile +++ b/arch/avr32/oprofile/Makefile | |||
@@ -5,4 +5,4 @@ oprofile-y := $(addprefix ../../../drivers/oprofile/, \ | |||
5 | event_buffer.o oprofile_files.o \ | 5 | event_buffer.o oprofile_files.o \ |
6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
7 | timer_int.o) | 7 | timer_int.o) |
8 | oprofile-y += op_model_avr32.o | 8 | oprofile-y += op_model_avr32.o backtrace.o |
diff --git a/arch/avr32/oprofile/backtrace.c b/arch/avr32/oprofile/backtrace.c new file mode 100644 index 000000000000..75d9ad6f99cf --- /dev/null +++ b/arch/avr32/oprofile/backtrace.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * AVR32 specific backtracing code for oprofile | ||
3 | * | ||
4 | * Copyright 2008 Weinmann GmbH | ||
5 | * | ||
6 | * Author: Nikolaus Voss <n.voss@weinmann.de> | ||
7 | * | ||
8 | * Based on i386 oprofile backtrace code by John Levon and David Smith | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/oprofile.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/uaccess.h> | ||
19 | |||
20 | /* The first two words of each frame on the stack look like this if we have | ||
21 | * frame pointers */ | ||
22 | struct frame_head { | ||
23 | unsigned long lr; | ||
24 | struct frame_head *fp; | ||
25 | }; | ||
26 | |||
27 | /* copied from arch/avr32/kernel/process.c */ | ||
28 | static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) | ||
29 | { | ||
30 | return (p > (unsigned long)tinfo) | ||
31 | && (p < (unsigned long)tinfo + THREAD_SIZE - 3); | ||
32 | } | ||
33 | |||
34 | /* copied from arch/x86/oprofile/backtrace.c */ | ||
35 | static struct frame_head *dump_user_backtrace(struct frame_head *head) | ||
36 | { | ||
37 | struct frame_head bufhead[2]; | ||
38 | |||
39 | /* Also check accessibility of one struct frame_head beyond */ | ||
40 | if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) | ||
41 | return NULL; | ||
42 | if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) | ||
43 | return NULL; | ||
44 | |||
45 | oprofile_add_trace(bufhead[0].lr); | ||
46 | |||
47 | /* frame pointers should strictly progress back up the stack | ||
48 | * (towards higher addresses) */ | ||
49 | if (bufhead[0].fp <= head) | ||
50 | return NULL; | ||
51 | |||
52 | return bufhead[0].fp; | ||
53 | } | ||
54 | |||
55 | void avr32_backtrace(struct pt_regs * const regs, unsigned int depth) | ||
56 | { | ||
57 | /* Get first frame pointer */ | ||
58 | struct frame_head *head = (struct frame_head *)(regs->r7); | ||
59 | |||
60 | if (!user_mode(regs)) { | ||
61 | #ifdef CONFIG_FRAME_POINTER | ||
62 | /* | ||
63 | * Traverse the kernel stack from frame to frame up to | ||
64 | * "depth" steps. | ||
65 | */ | ||
66 | while (depth-- && valid_stack_ptr(task_thread_info(current), | ||
67 | (unsigned long)head)) { | ||
68 | oprofile_add_trace(head->lr); | ||
69 | if (head->fp <= head) | ||
70 | break; | ||
71 | head = head->fp; | ||
72 | } | ||
73 | #endif | ||
74 | } else { | ||
75 | /* Assume we have frame pointers in user mode process */ | ||
76 | while (depth-- && head) | ||
77 | head = dump_user_backtrace(head); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | |||
diff --git a/arch/avr32/oprofile/op_model_avr32.c b/arch/avr32/oprofile/op_model_avr32.c index df42325c7f81..a3e9b3c4845a 100644 --- a/arch/avr32/oprofile/op_model_avr32.c +++ b/arch/avr32/oprofile/op_model_avr32.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #define AVR32_PERFCTR_IRQ_GROUP 0 | 22 | #define AVR32_PERFCTR_IRQ_GROUP 0 |
23 | #define AVR32_PERFCTR_IRQ_LINE 1 | 23 | #define AVR32_PERFCTR_IRQ_LINE 1 |
24 | 24 | ||
25 | void avr32_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
26 | |||
25 | enum { PCCNT, PCNT0, PCNT1, NR_counter }; | 27 | enum { PCCNT, PCNT0, PCNT1, NR_counter }; |
26 | 28 | ||
27 | struct avr32_perf_counter { | 29 | struct avr32_perf_counter { |
@@ -223,6 +225,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
223 | memcpy(ops, &avr32_perf_counter_ops, | 225 | memcpy(ops, &avr32_perf_counter_ops, |
224 | sizeof(struct oprofile_operations)); | 226 | sizeof(struct oprofile_operations)); |
225 | 227 | ||
228 | ops->backtrace = avr32_backtrace; | ||
229 | |||
226 | printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n"); | 230 | printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n"); |
227 | 231 | ||
228 | return 0; | 232 | return 0; |