Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc

Pull sparc fixes from David Miller:

1) Fix NULL oops in Schizo PCI controller error handler.

2) Fix race between xchg and other operations on 32-bit sparc, from
Andreas Larsson.

3) swab*() helpers need a dummy memory input operand to show data flow
on 64-bit sparc.

4) Fix RCU warnings due to missing irq_{enter,exit}() around
generic_smp_call_function*() calls.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Fix constraints on swab helpers.
sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks
sparc64: Do irq_{enter,exit}() around generic_smp_call_function*().
sparc64: Fix crashes in schizo_pcierr_intr_other().

Changed files
+43 -20
arch
sparc
+1 -1
arch/sparc/include/asm/atomic_32.h
··· 22 22 23 23 int atomic_add_return(int, atomic_t *); 24 24 int atomic_cmpxchg(atomic_t *, int, int); 25 - #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 25 + int atomic_xchg(atomic_t *, int); 26 26 int __atomic_add_unless(atomic_t *, int, int); 27 27 void atomic_set(atomic_t *, int); 28 28
+2 -10
arch/sparc/include/asm/cmpxchg_32.h
··· 11 11 #ifndef __ARCH_SPARC_CMPXCHG__ 12 12 #define __ARCH_SPARC_CMPXCHG__ 13 13 14 - static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val) 15 - { 16 - __asm__ __volatile__("swap [%2], %0" 17 - : "=&r" (val) 18 - : "0" (val), "r" (m) 19 - : "memory"); 20 - return val; 21 - } 22 - 14 + unsigned long __xchg_u32(volatile u32 *m, u32 new); 23 15 void __xchg_called_with_bad_pointer(void); 24 16 25 17 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) 26 18 { 27 19 switch (size) { 28 20 case 4: 29 - return xchg_u32(ptr, x); 21 + return __xchg_u32(ptr, x); 30 22 } 31 23 __xchg_called_with_bad_pointer(); 32 24 return x;
+6 -6
arch/sparc/include/uapi/asm/swab.h
··· 9 9 { 10 10 __u16 ret; 11 11 12 - __asm__ __volatile__ ("lduha [%1] %2, %0" 12 + __asm__ __volatile__ ("lduha [%2] %3, %0" 13 13 : "=r" (ret) 14 - : "r" (addr), "i" (ASI_PL)); 14 + : "m" (*addr), "r" (addr), "i" (ASI_PL)); 15 15 return ret; 16 16 } 17 17 #define __arch_swab16p __arch_swab16p ··· 20 20 { 21 21 __u32 ret; 22 22 23 - __asm__ __volatile__ ("lduwa [%1] %2, %0" 23 + __asm__ __volatile__ ("lduwa [%2] %3, %0" 24 24 : "=r" (ret) 25 - : "r" (addr), "i" (ASI_PL)); 25 + : "m" (*addr), "r" (addr), "i" (ASI_PL)); 26 26 return ret; 27 27 } 28 28 #define __arch_swab32p __arch_swab32p ··· 31 31 { 32 32 __u64 ret; 33 33 34 - __asm__ __volatile__ ("ldxa [%1] %2, %0" 34 + __asm__ __volatile__ ("ldxa [%2] %3, %0" 35 35 : "=r" (ret) 36 - : "r" (addr), "i" (ASI_PL)); 36 + : "m" (*addr), "r" (addr), "i" (ASI_PL)); 37 37 return ret; 38 38 } 39 39 #define __arch_swab64p __arch_swab64p
+3 -3
arch/sparc/kernel/pci_schizo.c
··· 581 581 { 582 582 unsigned long csr_reg, csr, csr_error_bits; 583 583 irqreturn_t ret = IRQ_NONE; 584 - u16 stat; 584 + u32 stat; 585 585 586 586 csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL; 587 587 csr = upa_readq(csr_reg); ··· 617 617 pbm->name); 618 618 ret = IRQ_HANDLED; 619 619 } 620 - pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat); 620 + pbm->pci_ops->read(pbm->pci_bus, 0, PCI_STATUS, 2, &stat); 621 621 if (stat & (PCI_STATUS_PARITY | 622 622 PCI_STATUS_SIG_TARGET_ABORT | 623 623 PCI_STATUS_REC_TARGET_ABORT | ··· 625 625 PCI_STATUS_SIG_SYSTEM_ERROR)) { 626 626 printk("%s: PCI bus error, PCI_STATUS[%04x]\n", 627 627 pbm->name, stat); 628 - pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff); 628 + pbm->pci_ops->write(pbm->pci_bus, 0, PCI_STATUS, 2, 0xffff); 629 629 ret = IRQ_HANDLED; 630 630 } 631 631 return ret;
+4
arch/sparc/kernel/smp_64.c
··· 816 816 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs) 817 817 { 818 818 clear_softint(1 << irq); 819 + irq_enter(); 819 820 generic_smp_call_function_interrupt(); 821 + irq_exit(); 820 822 } 821 823 822 824 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs) 823 825 { 824 826 clear_softint(1 << irq); 827 + irq_enter(); 825 828 generic_smp_call_function_single_interrupt(); 829 + irq_exit(); 826 830 } 827 831 828 832 static void tsb_sync(void *info)
+27
arch/sparc/lib/atomic32.c
··· 45 45 46 46 #undef ATOMIC_OP 47 47 48 + int atomic_xchg(atomic_t *v, int new) 49 + { 50 + int ret; 51 + unsigned long flags; 52 + 53 + spin_lock_irqsave(ATOMIC_HASH(v), flags); 54 + ret = v->counter; 55 + v->counter = new; 56 + spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 57 + return ret; 58 + } 59 + EXPORT_SYMBOL(atomic_xchg); 60 + 48 61 int atomic_cmpxchg(atomic_t *v, int old, int new) 49 62 { 50 63 int ret; ··· 150 137 return (unsigned long)prev; 151 138 } 152 139 EXPORT_SYMBOL(__cmpxchg_u32); 140 + 141 + unsigned long __xchg_u32(volatile u32 *ptr, u32 new) 142 + { 143 + unsigned long flags; 144 + u32 prev; 145 + 146 + spin_lock_irqsave(ATOMIC_HASH(ptr), flags); 147 + prev = *ptr; 148 + *ptr = new; 149 + spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags); 150 + 151 + return (unsigned long)prev; 152 + } 153 + EXPORT_SYMBOL(__xchg_u32);