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
2222
2323 int atomic_add_return(int, atomic_t *);
2424 int atomic_cmpxchg(atomic_t *, int, int);
25−#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
25+int atomic_xchg(atomic_t *, int);
2626 int __atomic_add_unless(atomic_t *, int, int);
2727 void atomic_set(atomic_t *, int);
2828
arch/sparc/include/asm/cmpxchg_32.h+2−10
@@ -11,22 +11,14 @@ · 10 unmodified lines
1111 #ifndef __ARCH_SPARC_CMPXCHG__
1212 #define __ARCH_SPARC_CMPXCHG__
1313
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);
2315 void __xchg_called_with_bad_pointer(void);
2416
2517 static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
2618 {
2719 switch (size) {
2820 case 4:
29− return xchg_u32(ptr, x);
21+ return __xchg_u32(ptr, x);
3022 }
3123 __xchg_called_with_bad_pointer();
3224 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
99 {
1010 __u16 ret;
1111
12− __asm__ __volatile__ ("lduha [%1] %2, %0"
12+ __asm__ __volatile__ ("lduha [%2] %3, %0"
1313 : "=r" (ret)
14− : "r" (addr), "i" (ASI_PL));
14+ : "m" (*addr), "r" (addr), "i" (ASI_PL));
1515 return ret;
1616 }
1717 #define __arch_swab16p __arch_swab16p
@@ -20,9 +20,9 @@ static inline __u32 __arch_swab32p(const __u32 *addr) · 2 unmodified lines
2020 {
2121 __u32 ret;
2222
23− __asm__ __volatile__ ("lduwa [%1] %2, %0"
23+ __asm__ __volatile__ ("lduwa [%2] %3, %0"
2424 : "=r" (ret)
25− : "r" (addr), "i" (ASI_PL));
25+ : "m" (*addr), "r" (addr), "i" (ASI_PL));
2626 return ret;
2727 }
2828 #define __arch_swab32p __arch_swab32p
@@ -31,9 +31,9 @@ static inline __u64 __arch_swab64p(const __u64 *addr) · 2 unmodified lines
3131 {
3232 __u64 ret;
3333
34− __asm__ __volatile__ ("ldxa [%1] %2, %0"
34+ __asm__ __volatile__ ("ldxa [%2] %3, %0"
3535 : "=r" (ret)
36− : "r" (addr), "i" (ASI_PL));
36+ : "m" (*addr), "r" (addr), "i" (ASI_PL));
3737 return ret;
3838 }
3939 #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
581581 {
582582 unsigned long csr_reg, csr, csr_error_bits;
583583 irqreturn_t ret = IRQ_NONE;
584− u16 stat;
584+ u32 stat;
585585
586586 csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
587587 csr = upa_readq(csr_reg);
@@ -617,7 +617,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) · 29 unmodified lines
617617 pbm->name);
618618 ret = IRQ_HANDLED;
619619 }
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);
621621 if (stat & (PCI_STATUS_PARITY |
622622 PCI_STATUS_SIG_TARGET_ABORT |
623623 PCI_STATUS_REC_TARGET_ABORT |
@@ -625,7 +625,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) · 1 unmodified line
625625 PCI_STATUS_SIG_SYSTEM_ERROR)) {
626626 printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
627627 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);
629629 ret = IRQ_HANDLED;
630630 }
631631 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
816816 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
817817 {
818818 clear_softint(1 << irq);
819+ irq_enter();
819820 generic_smp_call_function_interrupt();
821+ irq_exit();
820822 }
821823
822824 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
823825 {
824826 clear_softint(1 << irq);
827+ irq_enter();
825828 generic_smp_call_function_single_interrupt();
829+ irq_exit();
826830 }
827831
828832 static void tsb_sync(void *info)
arch/sparc/lib/atomic32.c+27−0
@@ -45,6 +45,19 @@ ATOMIC_OP(add, +=) · 44 unmodified lines
4545
4646 #undef ATOMIC_OP
4747
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+
4861 int atomic_cmpxchg(atomic_t *v, int old, int new)
4962 {
5063 int ret;
@@ -137,3 +150,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) · 86 unmodified lines
137150 return (unsigned long)prev;
138151 }
139152 EXPORT_SYMBOL(__cmpxchg_u32);
153+
154+unsigned 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+}
166+EXPORT_SYMBOL(__xchg_u32);