History

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().

Linus Torvalds committed 12 years ago

Commit 435e46f2 parents 0fbae13 5a2b59d6 files · +43 −20Browse files

Unified · Split

6 files
  1. arch/sparc/include/asm/atomic_32.h +1 −1
  2. arch/sparc/include/asm/cmpxchg_32.h +2 −10
  3. arch/sparc/include/uapi/asm/swab.h +6 −6
  4. arch/sparc/kernel/pci_schizo.c +3 −3
  5. arch/sparc/kernel/smp_64.c +4 −0
  6. arch/sparc/lib/atomic32.c +27 −0
arch/sparc/include/asm/atomic_32.h+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
22 22
23int atomic_add_return(int, atomic_t *);23int atomic_add_return(int, atomic_t *);
24int atomic_cmpxchg(atomic_t *, int, int);24int atomic_cmpxchg(atomic_t *, int, int);
25#define atomic_xchg(v, new) (xchg(&((v)->counter), new))25int atomic_xchg(atomic_t *, int);
26int __atomic_add_unless(atomic_t *, int, int);26int __atomic_add_unless(atomic_t *, int, int);
27void atomic_set(atomic_t *, int);27void atomic_set(atomic_t *, int);
28 28
arch/sparc/include/asm/cmpxchg_32.h+2−10
@@ -11,22 +11,14 @@ · 10 unmodified lines
11#ifndef __ARCH_SPARC_CMPXCHG__11#ifndef __ARCH_SPARC_CMPXCHG__
12#define __ARCH_SPARC_CMPXCHG__12#define __ARCH_SPARC_CMPXCHG__
13 13
14static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)14unsigned long __xchg_u32(volatile u32 *m, u32 new);
15{
16 __asm__ __volatile__("swap [%2], %0"
17 : "=&r" (val)
18 : "0" (val), "r" (m)
19 : "memory");
20 return val;
21}
22
23void __xchg_called_with_bad_pointer(void);15void __xchg_called_with_bad_pointer(void);
24 16
25static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)17static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
26{18{
27 switch (size) {19 switch (size) {
28 case 4:20 case 4:
29 return xchg_u32(ptr, x);21 return __xchg_u32(ptr, x);
30 }22 }
31 __xchg_called_with_bad_pointer();23 __xchg_called_with_bad_pointer();
32 return x;24 return x;
arch/sparc/include/uapi/asm/swab.h+6−6
@@ -9,9 +9,9 @@ static inline __u16 __arch_swab16p(const __u16 *addr) · 8 unmodified lines
9{9{
10 __u16 ret;10 __u16 ret;
11 11
12 __asm__ __volatile__ ("lduha [%1] %2, %0"12 __asm__ __volatile__ ("lduha [%2] %3, %0"
13 : "=r" (ret)13 : "=r" (ret)
14 : "r" (addr), "i" (ASI_PL));14 : "m" (*addr), "r" (addr), "i" (ASI_PL));
15 return ret;15 return ret;
16}16}
17#define __arch_swab16p __arch_swab16p17#define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr) · 2 unmodified lines
20{20{
21 __u32 ret;21 __u32 ret;
22 22
23 __asm__ __volatile__ ("lduwa [%1] %2, %0"23 __asm__ __volatile__ ("lduwa [%2] %3, %0"
24 : "=r" (ret)24 : "=r" (ret)
25 : "r" (addr), "i" (ASI_PL));25 : "m" (*addr), "r" (addr), "i" (ASI_PL));
26 return ret;26 return ret;
27}27}
28#define __arch_swab32p __arch_swab32p28#define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr) · 2 unmodified lines
31{31{
32 __u64 ret;32 __u64 ret;
33 33
34 __asm__ __volatile__ ("ldxa [%1] %2, %0"34 __asm__ __volatile__ ("ldxa [%2] %3, %0"
35 : "=r" (ret)35 : "=r" (ret)
36 : "r" (addr), "i" (ASI_PL));36 : "m" (*addr), "r" (addr), "i" (ASI_PL));
37 return ret;37 return ret;
38}38}
39#define __arch_swab64p __arch_swab64p39#define __arch_swab64p __arch_swab64p
arch/sparc/kernel/pci_schizo.c+3−3
@@ -581,7 +581,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) · 580 unmodified lines
581{581{
582 unsigned long csr_reg, csr, csr_error_bits;582 unsigned long csr_reg, csr, csr_error_bits;
583 irqreturn_t ret = IRQ_NONE;583 irqreturn_t ret = IRQ_NONE;
584 u16 stat;584 u32 stat;
585 585
586 csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;586 csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
587 csr = upa_readq(csr_reg);587 csr = upa_readq(csr_reg);
@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) · 29 unmodified lines
617 pbm->name);617 pbm->name);
618 ret = IRQ_HANDLED;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 if (stat & (PCI_STATUS_PARITY |621 if (stat & (PCI_STATUS_PARITY |
622 PCI_STATUS_SIG_TARGET_ABORT |622 PCI_STATUS_SIG_TARGET_ABORT |
623 PCI_STATUS_REC_TARGET_ABORT |623 PCI_STATUS_REC_TARGET_ABORT |
@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) · 1 unmodified line
625 PCI_STATUS_SIG_SYSTEM_ERROR)) {625 PCI_STATUS_SIG_SYSTEM_ERROR)) {
626 printk("%s: PCI bus error, PCI_STATUS[%04x]\n",626 printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
627 pbm->name, stat);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 ret = IRQ_HANDLED;629 ret = IRQ_HANDLED;
630 }630 }
631 return ret;631 return ret;
arch/sparc/kernel/smp_64.c+4−0
@@ -816,13 +816,17 @@ void arch_send_call_function_single_ipi(int cpu) · 815 unmodified lines
816void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)816void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
817{817{
818 clear_softint(1 << irq);818 clear_softint(1 << irq);
819 irq_enter();
819 generic_smp_call_function_interrupt();820 generic_smp_call_function_interrupt();
821 irq_exit();
820}822}
821 823
822void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)824void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
823{825{
824 clear_softint(1 << irq);826 clear_softint(1 << irq);
827 irq_enter();
825 generic_smp_call_function_single_interrupt();828 generic_smp_call_function_single_interrupt();
829 irq_exit();
826}830}
827 831
828static void tsb_sync(void *info)832static void tsb_sync(void *info)
arch/sparc/lib/atomic32.c+27−0
@@ -45,6 +45,19 @@ ATOMIC_OP(add, +=) · 44 unmodified lines
45 45
46#undef ATOMIC_OP46#undef ATOMIC_OP
47 47
48int 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}
59EXPORT_SYMBOL(atomic_xchg);
60
48int atomic_cmpxchg(atomic_t *v, int old, int new)61int atomic_cmpxchg(atomic_t *v, int old, int new)
49{62{
50 int ret;63 int ret;
@@ -137,3 +150,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) · 86 unmodified lines
137 return (unsigned long)prev;150 return (unsigned long)prev;
138}151}
139EXPORT_SYMBOL(__cmpxchg_u32);152EXPORT_SYMBOL(__cmpxchg_u32);
153
154unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
155{
156 unsigned long flags;
157 u32 prev;
158
159 spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
160 prev = *ptr;
161 *ptr = new;
162 spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
163
164 return (unsigned long)prev;
165}
166EXPORT_SYMBOL(__xchg_u32);