Commit 7c6d4dca authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha

Pull alpha architecture fixes from Matt Turner:
 "This contains mostly clean ups and fixes but also an implementation of
  atomic64_dec_if_positive() and a pair of new syscalls"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha:
  alpha: Use handle_percpu_irq for the timer interrupt
  alpha: Force the user-visible HZ to a constant 1024.
  alpha: Don't if-out dp264_device_interrupt.
  alpha: Use __builtin_alpha_rpcc
  alpha: Fix type compatibility warning for marvel_map_irq
  alpha: Generate dwarf2 unwind info for various kernel entry points.
  alpha: Implement atomic64_dec_if_positive
  alpha: Improve atomic_add_unless
  alpha: Modernize lib/mpi/longlong.h
  alpha: Add kcmp and finit_module syscalls
  alpha: locks: remove unused arch_*_relax operations
  alpha: kernel: typo issue, using '1' instead of '11'
  alpha: kernel: using memcpy() instead of strcpy()
  alpha: Convert print_symbol to %pSR
parents a030cbc3 dff64649
...@@ -15,6 +15,7 @@ config ALPHA ...@@ -15,6 +15,7 @@ config ALPHA
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select GENERIC_SMP_IDLE_THREAD select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE select GENERIC_CMOS_UPDATE
select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNCPY_FROM_USER
......
...@@ -186,17 +186,24 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) ...@@ -186,17 +186,24 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
*/ */
static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
{ {
int c, old; int c, new, old;
c = atomic_read(v); smp_mb();
for (;;) { __asm__ __volatile__(
if (unlikely(c == (u))) "1: ldl_l %[old],%[mem]\n"
break; " cmpeq %[old],%[u],%[c]\n"
old = atomic_cmpxchg((v), c, c + (a)); " addl %[old],%[a],%[new]\n"
if (likely(old == c)) " bne %[c],2f\n"
break; " stl_c %[new],%[mem]\n"
c = old; " beq %[new],3f\n"
} "2:\n"
return c; ".subsection 2\n"
"3: br 1b\n"
".previous"
: [old] "=&r"(old), [new] "=&r"(new), [c] "=&r"(c)
: [mem] "m"(*v), [a] "rI"(a), [u] "rI"((long)u)
: "memory");
smp_mb();
return old;
} }
...@@ -207,21 +214,56 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) ...@@ -207,21 +214,56 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
* @u: ...unless v is equal to u. * @u: ...unless v is equal to u.
* *
* Atomically adds @a to @v, so long as it was not @u. * Atomically adds @a to @v, so long as it was not @u.
* Returns the old value of @v. * Returns true iff @v was not @u.
*/ */
static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
{ {
long c, old; long c, tmp;
c = atomic64_read(v); smp_mb();
for (;;) { __asm__ __volatile__(
if (unlikely(c == (u))) "1: ldq_l %[tmp],%[mem]\n"
break; " cmpeq %[tmp],%[u],%[c]\n"
old = atomic64_cmpxchg((v), c, c + (a)); " addq %[tmp],%[a],%[tmp]\n"
if (likely(old == c)) " bne %[c],2f\n"
break; " stq_c %[tmp],%[mem]\n"
c = old; " beq %[tmp],3f\n"
} "2:\n"
return c != (u); ".subsection 2\n"
"3: br 1b\n"
".previous"
: [tmp] "=&r"(tmp), [c] "=&r"(c)
: [mem] "m"(*v), [a] "rI"(a), [u] "rI"(u)
: "memory");
smp_mb();
return !c;
}
/*
* atomic64_dec_if_positive - decrement by 1 if old value positive
* @v: pointer of type atomic_t
*
* The function returns the old value of *v minus 1, even if
* the atomic variable, v, was not decremented.
*/
static inline long atomic64_dec_if_positive(atomic64_t *v)
{
long old, tmp;
smp_mb();
__asm__ __volatile__(
"1: ldq_l %[old],%[mem]\n"
" subq %[old],1,%[tmp]\n"
" ble %[old],2f\n"
" stq_c %[tmp],%[mem]\n"
" beq %[tmp],3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: [old] "=&r"(old), [tmp] "=&r"(tmp)
: [mem] "m"(*v)
: "memory");
smp_mb();
return old - 1;
} }
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
......
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
#include <uapi/asm/param.h> #include <uapi/asm/param.h>
#define HZ CONFIG_HZ # undef HZ
#define USER_HZ HZ # define HZ CONFIG_HZ
# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ # define USER_HZ 1024
# define CLOCKS_PER_SEC USER_HZ /* frequency at which times() counts */
#endif /* _ASM_ALPHA_PARAM_H */ #endif /* _ASM_ALPHA_PARAM_H */
...@@ -168,8 +168,4 @@ static inline void arch_write_unlock(arch_rwlock_t * lock) ...@@ -168,8 +168,4 @@ static inline void arch_write_unlock(arch_rwlock_t * lock)
#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
#define arch_spin_relax(lock) cpu_relax()
#define arch_read_relax(lock) cpu_relax()
#define arch_write_relax(lock) cpu_relax()
#endif /* _ALPHA_SPINLOCK_H */ #endif /* _ALPHA_SPINLOCK_H */
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
#include <uapi/asm/unistd.h> #include <uapi/asm/unistd.h>
#define NR_SYSCALLS 508
#define NR_SYSCALLS 506
#define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64 #define __ARCH_WANT_STAT64
......
#ifndef _UAPI_ASM_ALPHA_PARAM_H #ifndef _UAPI_ASM_ALPHA_PARAM_H
#define _UAPI_ASM_ALPHA_PARAM_H #define _UAPI_ASM_ALPHA_PARAM_H
/* ??? Gross. I don't want to parameterize this, and supposedly the
hardware ignores reprogramming. We also need userland buy-in to the
change in HZ, since this is visible in the wait4 resources etc. */
#ifndef __KERNEL__
#define HZ 1024 #define HZ 1024
#endif
#define EXEC_PAGESIZE 8192 #define EXEC_PAGESIZE 8192
...@@ -17,5 +11,4 @@ ...@@ -17,5 +11,4 @@
#define MAXHOSTNAMELEN 64 /* max length of hostname */ #define MAXHOSTNAMELEN 64 /* max length of hostname */
#endif /* _UAPI_ASM_ALPHA_PARAM_H */ #endif /* _UAPI_ASM_ALPHA_PARAM_H */
...@@ -467,5 +467,7 @@ ...@@ -467,5 +467,7 @@
#define __NR_sendmmsg 503 #define __NR_sendmmsg 503
#define __NR_process_vm_readv 504 #define __NR_process_vm_readv 504
#define __NR_process_vm_writev 505 #define __NR_process_vm_writev 505
#define __NR_kcmp 506
#define __NR_finit_module 507
#endif /* _UAPI_ALPHA_UNISTD_H */ #endif /* _UAPI_ALPHA_UNISTD_H */
This diff is collapsed.
...@@ -236,7 +236,7 @@ void __init ...@@ -236,7 +236,7 @@ void __init
init_rtc_irq(void) init_rtc_irq(void)
{ {
irq_set_chip_and_handler_name(RTC_IRQ, &dummy_irq_chip, irq_set_chip_and_handler_name(RTC_IRQ, &dummy_irq_chip,
handle_simple_irq, "RTC"); handle_percpu_irq, "RTC");
setup_irq(RTC_IRQ, &timer_irqaction); setup_irq(RTC_IRQ, &timer_irqaction);
} }
......
...@@ -264,9 +264,10 @@ recv_secondary_console_msg(void) ...@@ -264,9 +264,10 @@ recv_secondary_console_msg(void)
if (cnt <= 0 || cnt >= 80) if (cnt <= 0 || cnt >= 80)
strcpy(buf, "<<< BOGUS MSG >>>"); strcpy(buf, "<<< BOGUS MSG >>>");
else { else {
cp1 = (char *) &cpu->ipc_buffer[11]; cp1 = (char *) &cpu->ipc_buffer[1];
cp2 = buf; cp2 = buf;
strcpy(cp2, cp1); memcpy(cp2, cp1, cnt);
cp2[cnt] = '\0';
while ((cp2 = strchr(cp2, '\r')) != 0) { while ((cp2 = strchr(cp2, '\r')) != 0) {
*cp2 = ' '; *cp2 = ' ';
......
...@@ -190,9 +190,6 @@ static struct irq_chip clipper_irq_type = { ...@@ -190,9 +190,6 @@ static struct irq_chip clipper_irq_type = {
static void static void
dp264_device_interrupt(unsigned long vector) dp264_device_interrupt(unsigned long vector)
{ {
#if 1
printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
#else
unsigned long pld; unsigned long pld;
unsigned int i; unsigned int i;
...@@ -210,12 +207,7 @@ dp264_device_interrupt(unsigned long vector) ...@@ -210,12 +207,7 @@ dp264_device_interrupt(unsigned long vector)
isa_device_interrupt(vector); isa_device_interrupt(vector);
else else
handle_irq(16 + i); handle_irq(16 + i);
#if 0
TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
tmp = TSUNAMI_cchip->dir0.csr;
#endif
} }
#endif
} }
static void static void
......
...@@ -317,8 +317,9 @@ marvel_init_irq(void) ...@@ -317,8 +317,9 @@ marvel_init_irq(void)
} }
static int static int
marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
{ {
struct pci_dev *dev = (struct pci_dev *)cdev;
struct pci_controller *hose = dev->sysdata; struct pci_controller *hose = dev->sysdata;
struct io7_port *io7_port = hose->sysdata; struct io7_port *io7_port = hose->sysdata;
struct io7 *io7 = io7_port->io7; struct io7 *io7 = io7_port->io7;
......
...@@ -524,6 +524,8 @@ sys_call_table: ...@@ -524,6 +524,8 @@ sys_call_table:
.quad sys_sendmmsg .quad sys_sendmmsg
.quad sys_process_vm_readv .quad sys_process_vm_readv
.quad sys_process_vm_writev /* 505 */ .quad sys_process_vm_writev /* 505 */
.quad sys_kcmp
.quad sys_finit_module
.size sys_call_table, . - sys_call_table .size sys_call_table, . - sys_call_table
.type sys_call_table, @object .type sys_call_table, @object
......
...@@ -105,9 +105,7 @@ void arch_irq_work_raise(void) ...@@ -105,9 +105,7 @@ void arch_irq_work_raise(void)
static inline __u32 rpcc(void) static inline __u32 rpcc(void)
{ {
__u32 result; return __builtin_alpha_rpcc();
asm volatile ("rpcc %0" : "=r"(result));
return result;
} }
int update_persistent_clock(struct timespec now) int update_persistent_clock(struct timespec now)
......
...@@ -66,8 +66,8 @@ dik_show_regs(struct pt_regs *regs, unsigned long *r9_15) ...@@ -66,8 +66,8 @@ dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
{ {
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx %s\n", printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx %s\n",
regs->pc, regs->r26, regs->ps, print_tainted()); regs->pc, regs->r26, regs->ps, print_tainted());
print_symbol("pc is at %s\n", regs->pc); printk("pc is at %pSR\n", (void *)regs->pc);
print_symbol("ra is at %s\n", regs->r26 ); printk("ra is at %pSR\n", (void *)regs->r26);
printk("v0 = %016lx t0 = %016lx t1 = %016lx\n", printk("v0 = %016lx t0 = %016lx t1 = %016lx\n",
regs->r0, regs->r1, regs->r2); regs->r0, regs->r1, regs->r2);
printk("t2 = %016lx t3 = %016lx t4 = %016lx\n", printk("t2 = %016lx t3 = %016lx t4 = %016lx\n",
...@@ -132,9 +132,7 @@ dik_show_trace(unsigned long *sp) ...@@ -132,9 +132,7 @@ dik_show_trace(unsigned long *sp)
continue; continue;
if (tmp >= (unsigned long) &_etext) if (tmp >= (unsigned long) &_etext)
continue; continue;
printk("[<%lx>]", tmp); printk("[<%lx>] %pSR\n", tmp, (void *)tmp);
print_symbol(" %s", tmp);
printk("\n");
if (i > 40) { if (i > 40) {
printk(" ..."); printk(" ...");
break; break;
......
...@@ -151,15 +151,12 @@ do { \ ...@@ -151,15 +151,12 @@ do { \
#endif /* __a29k__ */ #endif /* __a29k__ */
#if defined(__alpha) && W_TYPE_SIZE == 64 #if defined(__alpha) && W_TYPE_SIZE == 64
#define umul_ppmm(ph, pl, m0, m1) \ #define umul_ppmm(ph, pl, m0, m1) \
do { \ do { \
UDItype __m0 = (m0), __m1 = (m1); \ UDItype __m0 = (m0), __m1 = (m1); \
__asm__ ("umulh %r1,%2,%0" \ (ph) = __builtin_alpha_umulh(__m0, __m1); \
: "=r" ((UDItype) ph) \ (pl) = __m0 * __m1; \
: "%rJ" (__m0), \ } while (0)
"rI" (__m1)); \
(pl) = __m0 * __m1; \
} while (0)
#define UMUL_TIME 46 #define UMUL_TIME 46
#ifndef LONGLONG_STANDALONE #ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \ #define udiv_qrnnd(q, r, n1, n0, d) \
...@@ -167,7 +164,7 @@ do { UDItype __r; \ ...@@ -167,7 +164,7 @@ do { UDItype __r; \
(q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
(r) = __r; \ (r) = __r; \
} while (0) } while (0)
extern UDItype __udiv_qrnnd(); extern UDItype __udiv_qrnnd(UDItype *, UDItype, UDItype, UDItype);
#define UDIV_TIME 220 #define UDIV_TIME 220
#endif /* LONGLONG_STANDALONE */ #endif /* LONGLONG_STANDALONE */
#endif /* __alpha */ #endif /* __alpha */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment