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 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 v0.10.2 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 diff --git a/arch/avr32/mach-at32ap/at32ap.c b/arch/avr32/mach-at32ap/at32ap.c index 90f207e..7c4987f 100644 --- a/arch/avr32/mach-at32ap/at32ap.c +++ b/arch/avr32/mach-at32ap/at32ap.c @@ -11,41 +11,10 @@ #include #include -#include - #include -#include - -struct at32_sm system_manager; - -static int __init at32_sm_init(void) -{ - struct resource *regs; - struct at32_sm *sm = &system_manager; - int ret = -ENXIO; - - regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0); - if (!regs) - goto fail; - - spin_lock_init(&sm->lock); - sm->pdev = &at32_sm_device; - - ret = -ENOMEM; - sm->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!sm->regs) - goto fail; - - return 0; - -fail: - printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret); - return ret; -} void __init setup_platform(void) { - at32_sm_init(); at32_clock_init(); at32_portmux_init(); } diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 4dda42d..5faa97e 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -17,14 +17,20 @@ #include #include #include -#include #include