From c6083cd61b5a64a1c73d1634744382f54cb99595 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 25 May 2007 18:47:47 -0700 Subject: [AVR32] faster avr32 unaligned access Use a more conventional implementation for unaligned access, and include an AT32AP-specific optimization: the CPU will handle unaligned words. The result is always faster and smaller for 8, 16, and 32 bit values. For 64 bit quantities, it's presumably larger. Signed-off-by: David Brownell Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/unaligned.h | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/unaligned.h b/include/asm-avr32/unaligned.h index 3042723..7913617 100644 --- a/include/asm-avr32/unaligned.h +++ b/include/asm-avr32/unaligned.h @@ -6,20 +6,31 @@ * implementation. The AVR32 AP implementation can handle unaligned * words, but halfwords must be halfword-aligned, and doublewords must * be word-aligned. - * - * TODO: Make all this CPU-specific and optimize. */ -#include +#include -/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ +#ifdef CONFIG_CPU_AT32AP7000 +/* REVISIT calling memmove() may be smaller for 64-bit values ... */ + +#undef get_unaligned #define get_unaligned(ptr) \ - ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) + ___get_unaligned(ptr, sizeof((*ptr))) +#define ___get_unaligned(ptr, size) \ + ((size == 4) ? *(ptr) : __get_unaligned(ptr, size)) + +#undef put_unaligned +#define put_unaligned(val, ptr) \ + ___put_unaligned((__u64)(val), ptr, sizeof((*ptr))) +#define ___put_unaligned(val, ptr, size) \ +do { \ + if (size == 4) \ + *(ptr) = (val); \ + else \ + __put_unaligned(val, ptr, size); \ +} while (0) -#define put_unaligned(val, ptr) \ - ({ __typeof__(*(ptr)) __tmp = (val); \ - memmove((ptr), &__tmp, sizeof(*(ptr))); \ - (void)0; }) +#endif #endif /* __ASM_AVR32_UNALIGNED_H */ -- cgit v1.1 From 7a5b80590772c29bba1d54d3685622177d6fe39f Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Jun 2007 12:58:30 +0200 Subject: [AVR32] Split SM device into PM, RTC, WDT and EIC Split the SM platform device into separate platform devices for PM, RTC, WDT and EIC. This is more correct according to the documentation and allows us to simplify the code a little. Also turn the EIC driver into a real platform driver. Signed-off-by: Haavard Skinnemoen Acked-by: Hans-Christian Egtvedt --- include/asm-avr32/arch-at32ap/sm.h | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 include/asm-avr32/arch-at32ap/sm.h (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/arch-at32ap/sm.h b/include/asm-avr32/arch-at32ap/sm.h deleted file mode 100644 index 265a9ea..0000000 --- a/include/asm-avr32/arch-at32ap/sm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * AT32 System Manager interface. - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_AT32_SM_H__ -#define __ASM_AVR32_AT32_SM_H__ - -struct irq_chip; -struct platform_device; - -struct at32_sm { - spinlock_t lock; - void __iomem *regs; - struct irq_chip *eim_chip; - unsigned int eim_first_irq; - struct platform_device *pdev; -}; - -extern struct platform_device at32_sm_device; -extern struct at32_sm system_manager; - -#endif /* __ASM_AVR32_AT32_SM_H__ */ -- cgit v1.1 From e122eaf69422e5d9ce93fc9786099098e3b9e1c4 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 20 Jun 2007 15:29:15 +0200 Subject: [AVR32] Remove optimization of unaligned word loads If we let unaligned word loads bypass the generic unaligned handling, gcc may combine it with a swap.b instruction and turn it into a ldwsp instruction, which does not work with unaligned addresses. Revert the optimization to prevent the RNDIS driver from crashing. Hopefully we'll figure something out later (it may be better to do the optimization in gcc.) Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/unaligned.h | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/unaligned.h b/include/asm-avr32/unaligned.h index 7913617..36f5fd4 100644 --- a/include/asm-avr32/unaligned.h +++ b/include/asm-avr32/unaligned.h @@ -6,31 +6,11 @@ * implementation. The AVR32 AP implementation can handle unaligned * words, but halfwords must be halfword-aligned, and doublewords must * be word-aligned. + * + * However, swapped word loads must be word-aligned so we can't + * optimize word loads in general. */ #include -#ifdef CONFIG_CPU_AT32AP7000 - -/* REVISIT calling memmove() may be smaller for 64-bit values ... */ - -#undef get_unaligned -#define get_unaligned(ptr) \ - ___get_unaligned(ptr, sizeof((*ptr))) -#define ___get_unaligned(ptr, size) \ - ((size == 4) ? *(ptr) : __get_unaligned(ptr, size)) - -#undef put_unaligned -#define put_unaligned(val, ptr) \ - ___put_unaligned((__u64)(val), ptr, sizeof((*ptr))) -#define ___put_unaligned(val, ptr, size) \ -do { \ - if (size == 4) \ - *(ptr) = (val); \ - else \ - __put_unaligned(val, ptr, size); \ -} while (0) - -#endif - #endif /* __ASM_AVR32_UNALIGNED_H */ -- cgit v1.1 From 9cf6cf58d06527fc5bc8e2965ddccdeca59ccee3 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Fri, 6 Jul 2007 14:31:55 +0200 Subject: [AVR32] Add Atmel SSC driver platform device to AT32AP architecture This patch adds register definitions, clocks and IRQs to the platform devices. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/arch-at32ap/board.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index 9744804..0215965 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h @@ -36,4 +36,18 @@ struct platform_device * at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, unsigned long fbmem_start, unsigned long fbmem_len); +/* depending on what's hooked up, not all SSC pins will be used */ +#define ATMEL_SSC_TK 0x01 +#define ATMEL_SSC_TF 0x02 +#define ATMEL_SSC_TD 0x04 +#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD) + +#define ATMEL_SSC_RK 0x10 +#define ATMEL_SSC_RF 0x20 +#define ATMEL_SSC_RD 0x40 +#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD) + +struct platform_device * +at32_add_device_ssc(unsigned int id, unsigned int flags); + #endif /* __ASM_ARCH_BOARD_H */ -- cgit v1.1 From 3da86ee4f1884c70edbf76f61bfbbe028d2d1685 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Wed, 18 Jul 2007 20:06:04 +0200 Subject: [AVR32] Fix atomic_add_unless() and atomic_sub_unless() These functions depend on "result" being initalized to 0, but "result" is not included as an input constraint to the inline assembly block following its initialization, only as an output constraint. Thus gcc thinks it doesn't need to initialize it, so result ends up undefined if the "unless" condition is true. This fixes an oops in sunrpc where the faulty atomics caused rpciod_up() to not start the workqueue as it should. Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/atomic.h b/include/asm-avr32/atomic.h index b9c2548..7ef3862 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) " mov %1, 1\n" "1:" : "=&r"(tmp), "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(a), "rKs21"(u) + : "m"(v->counter), "rKs21"(a), "rKs21"(u), "1"(result) : "cc", "memory"); return result; @@ -137,7 +137,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) " mov %1, 1\n" "1:" : "=&r"(tmp), "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "r"(a), "ir"(u) + : "m"(v->counter), "r"(a), "ir"(u), "1"(result) : "cc", "memory"); } -- cgit v1.1