summaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-sparc64')
-rw-r--r--include/asm-sparc64/pci.h2
-rw-r--r--include/asm-sparc64/spinlock.h160
-rw-r--r--include/asm-sparc64/spinlock_types.h20
-rw-r--r--include/asm-sparc64/system.h49
4 files changed, 86 insertions, 145 deletions
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index a4ab0ec7143a..89bd71b1c0d8 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -269,6 +269,8 @@ extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
+
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index a02c4370eb42..ec85d12d73b9 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -29,24 +29,13 @@
* must be pre-V9 branches.
*/
-#ifndef CONFIG_DEBUG_SPINLOCK
+#define __raw_spin_is_locked(lp) ((lp)->lock != 0)
-typedef struct {
- volatile unsigned char lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) {0,}
+#define __raw_spin_unlock_wait(lp) \
+ do { rmb(); \
+ } while((lp)->lock)
-#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(lp) ((lp)->lock != 0)
-
-#define spin_unlock_wait(lp) \
-do { rmb(); \
-} while((lp)->lock)
-
-static inline void _raw_spin_lock(spinlock_t *lock)
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
unsigned long tmp;
@@ -67,7 +56,7 @@ static inline void _raw_spin_lock(spinlock_t *lock)
: "memory");
}
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
unsigned long result;
@@ -81,7 +70,7 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
return (result == 0UL);
}
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
__asm__ __volatile__(
" membar #StoreStore | #LoadStore\n"
@@ -91,7 +80,7 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
: "memory");
}
-static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags)
+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
{
unsigned long tmp1, tmp2;
@@ -115,51 +104,9 @@ static inline void _raw_spin_lock_flags(spinlock_t *lock, unsigned long flags)
: "memory");
}
-#else /* !(CONFIG_DEBUG_SPINLOCK) */
-
-typedef struct {
- volatile unsigned char lock;
- unsigned int owner_pc, owner_cpu;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} spinlock_t;
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, 0xff }
-#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0)
-#define spin_is_locked(__lock) ((__lock)->lock != 0)
-#define spin_unlock_wait(__lock) \
-do { \
- rmb(); \
-} while((__lock)->lock)
-
-extern void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller);
-extern void _do_spin_unlock(spinlock_t *lock);
-extern int _do_spin_trylock(spinlock_t *lock, unsigned long caller);
-
-#define _raw_spin_trylock(lp) \
- _do_spin_trylock(lp, (unsigned long) __builtin_return_address(0))
-#define _raw_spin_lock(lock) \
- _do_spin_lock(lock, "spin_lock", \
- (unsigned long) __builtin_return_address(0))
-#define _raw_spin_unlock(lock) _do_spin_unlock(lock)
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
-#ifndef CONFIG_DEBUG_SPINLOCK
-
-typedef struct {
- volatile unsigned int lock;
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) {0,}
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-
-static void inline __read_lock(rwlock_t *lock)
+static void inline __read_lock(raw_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -184,7 +131,7 @@ static void inline __read_lock(rwlock_t *lock)
: "memory");
}
-static void inline __read_unlock(rwlock_t *lock)
+static void inline __read_unlock(raw_rwlock_t *lock)
{
unsigned long tmp1, tmp2;
@@ -201,7 +148,7 @@ static void inline __read_unlock(rwlock_t *lock)
: "memory");
}
-static void inline __write_lock(rwlock_t *lock)
+static void inline __write_lock(raw_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2;
@@ -228,7 +175,7 @@ static void inline __write_lock(rwlock_t *lock)
: "memory");
}
-static void inline __write_unlock(rwlock_t *lock)
+static void inline __write_unlock(raw_rwlock_t *lock)
{
__asm__ __volatile__(
" membar #LoadStore | #StoreStore\n"
@@ -238,7 +185,7 @@ static void inline __write_unlock(rwlock_t *lock)
: "memory");
}
-static int inline __write_trylock(rwlock_t *lock)
+static int inline __write_trylock(raw_rwlock_t *lock)
{
unsigned long mask, tmp1, tmp2, result;
@@ -263,78 +210,15 @@ static int inline __write_trylock(rwlock_t *lock)
return result;
}
-#define _raw_read_lock(p) __read_lock(p)
-#define _raw_read_unlock(p) __read_unlock(p)
-#define _raw_write_lock(p) __write_lock(p)
-#define _raw_write_unlock(p) __write_unlock(p)
-#define _raw_write_trylock(p) __write_trylock(p)
-
-#else /* !(CONFIG_DEBUG_SPINLOCK) */
-
-typedef struct {
- volatile unsigned long lock;
- unsigned int writer_pc, writer_cpu;
- unsigned int reader_pc[NR_CPUS];
-#ifdef CONFIG_PREEMPT
- unsigned int break_lock;
-#endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { } }
-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
-
-extern void _do_read_lock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_read_unlock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_write_lock(rwlock_t *rw, char *str, unsigned long caller);
-extern void _do_write_unlock(rwlock_t *rw, unsigned long caller);
-extern int _do_write_trylock(rwlock_t *rw, char *str, unsigned long caller);
-
-#define _raw_read_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_lock(lock, "read_lock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_read_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_read_unlock(lock, "read_unlock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_lock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_lock(lock, "write_lock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_unlock(lock) \
-do { unsigned long flags; \
- local_irq_save(flags); \
- _do_write_unlock(lock, \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
-} while(0)
-
-#define _raw_write_trylock(lock) \
-({ unsigned long flags; \
- int val; \
- local_irq_save(flags); \
- val = _do_write_trylock(lock, "write_trylock", \
- (unsigned long) __builtin_return_address(0)); \
- local_irq_restore(flags); \
- val; \
-})
-
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
-#define read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
-#define write_can_lock(rw) (!(rw)->lock)
+#define __raw_read_lock(p) __read_lock(p)
+#define __raw_read_unlock(p) __read_unlock(p)
+#define __raw_write_lock(p) __write_lock(p)
+#define __raw_write_unlock(p) __write_unlock(p)
+#define __raw_write_trylock(p) __write_trylock(p)
+
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
+#define __raw_write_can_lock(rw) (!(rw)->lock)
#endif /* !(__ASSEMBLY__) */
diff --git a/include/asm-sparc64/spinlock_types.h b/include/asm-sparc64/spinlock_types.h
new file mode 100644
index 000000000000..e128112a0d7c
--- /dev/null
+++ b/include/asm-sparc64/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __SPARC64_SPINLOCK_TYPES_H
+#define __SPARC64_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned char lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 5e94c05dc2fc..b5417529f6f1 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -28,13 +28,48 @@ enum sparc_cpu {
#define ARCH_SUN4C_SUN4 0
#define ARCH_SUN4 0
-extern void mb(void);
-extern void rmb(void);
-extern void wmb(void);
-extern void membar_storeload(void);
-extern void membar_storeload_storestore(void);
-extern void membar_storeload_loadload(void);
-extern void membar_storestore_loadstore(void);
+/* These are here in an effort to more fully work around Spitfire Errata
+ * #51. Essentially, if a memory barrier occurs soon after a mispredicted
+ * branch, the chip can stop executing instructions until a trap occurs.
+ * Therefore, if interrupts are disabled, the chip can hang forever.
+ *
+ * It used to be believed that the memory barrier had to be right in the
+ * delay slot, but a case has been traced recently wherein the memory barrier
+ * was one instruction after the branch delay slot and the chip still hung.
+ * The offending sequence was the following in sym_wakeup_done() of the
+ * sym53c8xx_2 driver:
+ *
+ * call sym_ccb_from_dsa, 0
+ * movge %icc, 0, %l0
+ * brz,pn %o0, .LL1303
+ * mov %o0, %l2
+ * membar #LoadLoad
+ *
+ * The branch has to be mispredicted for the bug to occur. Therefore, we put
+ * the memory barrier explicitly into a "branch always, predicted taken"
+ * delay slot to avoid the problem case.
+ */
+#define membar_safe(type) \
+do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
+ " membar " type "\n" \
+ "1:\n" \
+ : : : "memory"); \
+} while (0)
+
+#define mb() \
+ membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
+#define rmb() \
+ membar_safe("#LoadLoad")
+#define wmb() \
+ membar_safe("#StoreStore")
+#define membar_storeload() \
+ membar_safe("#StoreLoad")
+#define membar_storeload_storestore() \
+ membar_safe("#StoreLoad | #StoreStore")
+#define membar_storeload_loadload() \
+ membar_safe("#StoreLoad | #LoadLoad")
+#define membar_storestore_loadstore() \
+ membar_safe("#StoreStore | #LoadStore")
#endif
OpenPOWER on IntegriCloud