diff options
Diffstat (limited to 'arch/avr32')
-rw-r--r-- | arch/avr32/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/avr32/include/asm/atomic.h | 125 | ||||
-rw-r--r-- | arch/avr32/kernel/kprobes.c | 2 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap700x.c | 19 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/include/mach/atmel-mci.h | 2 |
5 files changed, 74 insertions, 75 deletions
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 00a0f3ccd6e..2a71b1cb984 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -9,6 +9,7 @@ generic-y += exec.h generic-y += futex.h generic-y += hash.h generic-y += irq_regs.h +generic-y += irq_work.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h index 0780f3f2415..2d07ce1c532 100644 --- a/arch/avr32/include/asm/atomic.h +++ b/arch/avr32/include/asm/atomic.h @@ -19,33 +19,46 @@ #define ATOMIC_INIT(i) { (i) } -#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_read(v) ACCESS_ONCE((v)->counter) #define atomic_set(v, i) (((v)->counter) = i) +#define ATOMIC_OP_RETURN(op, asm_op, asm_con) \ +static inline int __atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int result; \ + \ + asm volatile( \ + "/* atomic_" #op "_return */\n" \ + "1: ssrf 5\n" \ + " ld.w %0, %2\n" \ + " " #asm_op " %0, %3\n" \ + " stcond %1, %0\n" \ + " brne 1b" \ + : "=&r" (result), "=o" (v->counter) \ + : "m" (v->counter), #asm_con (i) \ + : "cc"); \ + \ + return result; \ +} + +ATOMIC_OP_RETURN(sub, sub, rKs21) +ATOMIC_OP_RETURN(add, add, r) + +#undef ATOMIC_OP_RETURN + /* - * atomic_sub_return - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t + * Probably found the reason why we want to use sub with the signed 21-bit + * limit, it uses one less register than the add instruction that can add up to + * 32-bit values. * - * Atomically subtracts @i from @v. Returns the resulting value. + * Both instructions are 32-bit, to use a 16-bit instruction the immediate is + * very small; 4 bit. + * + * sub 32-bit, type IV, takes a register and subtracts a 21-bit immediate. + * add 32-bit, type II, adds two register values together. */ -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int result; - - asm volatile( - "/* atomic_sub_return */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " sub %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(i) - : "cc"); - - return result; -} +#define IS_21BIT_CONST(i) \ + (__builtin_constant_p(i) && ((i) >= -1048575) && ((i) <= 1048576)) /* * atomic_add_return - add integer to atomic variable @@ -56,51 +69,25 @@ static inline int atomic_sub_return(int i, atomic_t *v) */ static inline int atomic_add_return(int i, atomic_t *v) { - int result; - - if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576)) - result = atomic_sub_return(-i, v); - else - asm volatile( - "/* atomic_add_return */\n" - "1: ssrf 5\n" - " ld.w %0, %1\n" - " add %0, %3\n" - " stcond %2, %0\n" - " brne 1b" - : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "r"(i) - : "cc", "memory"); + if (IS_21BIT_CONST(i)) + return __atomic_sub_return(-i, v); - return result; + return __atomic_add_return(i, v); } /* - * atomic_sub_unless - sub unless the number is a given value + * atomic_sub_return - subtract the atomic variable + * @i: integer value to subtract * @v: pointer of type atomic_t - * @a: the amount to subtract from v... - * @u: ...unless v is equal to u. * - * Atomically subtract @a from @v, so long as it was not @u. - * Returns the old value of @v. -*/ -static inline void atomic_sub_unless(atomic_t *v, int a, int u) + * Atomically subtracts @i from @v. Returns the resulting value. + */ +static inline int atomic_sub_return(int i, atomic_t *v) { - int tmp; + if (IS_21BIT_CONST(i)) + return __atomic_sub_return(i, v); - asm volatile( - "/* atomic_sub_unless */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " cp.w %0, %4\n" - " breq 1f\n" - " sub %0, %3\n" - " stcond %1, %0\n" - " brne 1b\n" - "1:" - : "=&r"(tmp), "=o"(v->counter) - : "m"(v->counter), "rKs21"(a), "rKs21"(u) - : "cc", "memory"); + return __atomic_add_return(-i, v); } /* @@ -116,9 +103,21 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int tmp, old = atomic_read(v); - if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) - atomic_sub_unless(v, -a, u); - else { + if (IS_21BIT_CONST(a)) { + asm volatile( + "/* __atomic_sub_unless */\n" + "1: ssrf 5\n" + " ld.w %0, %2\n" + " cp.w %0, %4\n" + " breq 1f\n" + " sub %0, %3\n" + " stcond %1, %0\n" + " brne 1b\n" + "1:" + : "=&r"(tmp), "=o"(v->counter) + : "m"(v->counter), "rKs21"(-a), "rKs21"(u) + : "cc", "memory"); + } else { asm volatile( "/* __atomic_add_unless */\n" "1: ssrf 5\n" @@ -137,6 +136,8 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) return old; } +#undef IS_21BIT_CONST + /* * atomic_sub_if_positive - conditionally subtract integer from atomic variable * @i: integer value to subtract diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c index f820e9f2552..a94ece4a72c 100644 --- a/arch/avr32/kernel/kprobes.c +++ b/arch/avr32/kernel/kprobes.c @@ -104,7 +104,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) static void __kprobes set_current_kprobe(struct kprobe *p) { - __get_cpu_var(current_kprobe) = p; + __this_cpu_write(current_kprobe, p); } static int __kprobes kprobe_handler(struct pt_regs *regs) diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index db85b5ec335..37b75602adf 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -7,7 +7,7 @@ */ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> #include <linux/fb.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -1356,10 +1356,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) goto fail; slave->sdata.dma_dev = &dw_dmac0_device.dev; - slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0) - | DWC_CFGH_DST_PER(1)); - slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL - | DWC_CFGL_HS_SRC_POL); + slave->sdata.src_id = 0; + slave->sdata.dst_id = 1; + slave->sdata.src_master = 1; + slave->sdata.dst_master = 0; data->dma_slave = slave; @@ -2052,8 +2052,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for capture should be configured. */ if (flags & AC97C_CAPTURE) { rx_dws->dma_dev = &dw_dmac0_device.dev; - rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); - rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + rx_dws->src_id = 3; rx_dws->src_master = 0; rx_dws->dst_master = 1; } @@ -2061,8 +2060,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, /* Check if DMA slave interface for playback should be configured. */ if (flags & AC97C_PLAYBACK) { tx_dws->dma_dev = &dw_dmac0_device.dev; - tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); - tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + tx_dws->dst_id = 4; tx_dws->src_master = 0; tx_dws->dst_master = 1; } @@ -2134,8 +2132,7 @@ at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) dws = &data->dws; dws->dma_dev = &dw_dmac0_device.dev; - dws->cfg_hi = DWC_CFGH_DST_PER(2); - dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + dws->dst_id = 2; dws->src_master = 0; dws->dst_master = 1; diff --git a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h index 4bba58561d5..11d7f4b28dc 100644 --- a/arch/avr32/mach-at32ap/include/mach/atmel-mci.h +++ b/arch/avr32/mach-at32ap/include/mach/atmel-mci.h @@ -1,7 +1,7 @@ #ifndef __MACH_ATMEL_MCI_H #define __MACH_ATMEL_MCI_H -#include <linux/dw_dmac.h> +#include <linux/platform_data/dma-dw.h> /** * struct mci_dma_data - DMA data for MCI interface |