Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision 13108f24b5d03e6fd6e35534dd89da620a897b88)
+++ kernel/generic/include/synch/spinlock.h	(revision 7a0359b903311f67678b4a0a3ebbcf0daf6eab38)
@@ -41,4 +41,5 @@
 #include <atomic.h>
 #include <debug.h>
+#include <arch/asm.h>
 
 #ifdef CONFIG_SMP
@@ -49,5 +50,5 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 	const char *name;
-#endif
+#endif /* CONFIG_DEBUG_SPINLOCK */
 } spinlock_t;
 
@@ -60,6 +61,7 @@
 
 /*
- * SPINLOCK_INITIALIZE is to be used for statically allocated spinlocks.
- * It declares and initializes the lock.
+ * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used
+ * for statically allocated spinlocks. They declare (either as global
+ * or static) symbol and initialize the lock.
  */
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -77,8 +79,11 @@
 	}
 
-#define spinlock_lock(lock)	spinlock_lock_debug((lock))
-#define spinlock_unlock(lock)	spinlock_unlock_debug((lock))
-
-#else
+#define ASSERT_SPINLOCK(expr, lock) \
+	ASSERT_VERBOSE(expr, (lock)->name)
+
+#define spinlock_lock(lock)    spinlock_lock_debug((lock))
+#define spinlock_unlock(lock)  spinlock_unlock_debug((lock))
+
+#else /* CONFIG_DEBUG_SPINLOCK */
 
 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
@@ -92,8 +97,11 @@
 	}
 
-#define spinlock_lock(lock)	atomic_lock_arch(&(lock)->val)
-#define spinlock_unlock(lock)	spinlock_unlock_nondebug((lock))
-
-#endif
+#define ASSERT_SPINLOCK(expr, lock) \
+	ASSERT(expr)
+
+#define spinlock_lock(lock)    atomic_lock_arch(&(lock)->val)
+#define spinlock_unlock(lock)  spinlock_unlock_nondebug((lock))
+
+#endif /* CONFIG_DEBUG_SPINLOCK */
 
 #define SPINLOCK_INITIALIZE(lock_name) \
@@ -103,8 +111,9 @@
 	SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
 
-extern void spinlock_initialize(spinlock_t *lock, const char *name);
-extern int spinlock_trylock(spinlock_t *lock);
-extern void spinlock_lock_debug(spinlock_t *lock);
-extern void spinlock_unlock_debug(spinlock_t *lock);
+extern void spinlock_initialize(spinlock_t *, const char *);
+extern int spinlock_trylock(spinlock_t *);
+extern void spinlock_lock_debug(spinlock_t *);
+extern void spinlock_unlock_debug(spinlock_t *);
+extern bool spinlock_locked(spinlock_t *);
 
 /** Unlock spinlock
@@ -113,6 +122,7 @@
  *
  * @param sl Pointer to spinlock_t structure.
- */
-static inline void spinlock_unlock_nondebug(spinlock_t *lock)
+ *
+ */
+NO_TRACE static inline void spinlock_unlock_nondebug(spinlock_t *lock)
 {
 	/*
@@ -141,10 +151,10 @@
 	}
 
-#else
+#else /* CONFIG_DEBUG_SPINLOCK */
 
 #define DEADLOCK_PROBE_INIT(pname)
 #define DEADLOCK_PROBE(pname, value)
 
-#endif
+#endif /* CONFIG_DEBUG_SPINLOCK */
 
 #else /* CONFIG_SMP */
@@ -160,4 +170,6 @@
 #define SPINLOCK_INITIALIZE_NAME(name, desc_name)
 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
+
+#define ASSERT_SPINLOCK(expr, lock)  ASSERT(expr)
 
 #define spinlock_initialize(lock, name)
@@ -166,12 +178,116 @@
 #define spinlock_trylock(lock)  (preemption_disable(), 1)
 #define spinlock_unlock(lock)   preemption_enable()
+#define spinlock_locked(lock)	1
+#define spinlock_unlocked(lock)	1
 
 #define DEADLOCK_PROBE_INIT(pname)
 #define DEADLOCK_PROBE(pname, value)
 
+#endif /* CONFIG_SMP */
+
+typedef struct {
+	SPINLOCK_DECLARE(lock);  /**< Spinlock */
+	bool guard;              /**< Flag whether ipl is valid */
+	ipl_t ipl;               /**< Original interrupt level */
+} irq_spinlock_t;
+
+#define IRQ_SPINLOCK_DECLARE(lock_name)  irq_spinlock_t lock_name
+#define IRQ_SPINLOCK_EXTERN(lock_name)   extern irq_spinlock_t lock_name
+
+#ifdef CONFIG_SMP
+
+#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
+	ASSERT_SPINLOCK(expr, &((irq_lock)->lock))
+
+/*
+ * IRQ_SPINLOCK_INITIALIZE and IRQ_SPINLOCK_STATIC_INITIALIZE are to be used
+ * for statically allocated interrupts-disabled spinlocks. They declare (either
+ * as global or static symbol) and initialize the lock.
+ */
+#ifdef CONFIG_DEBUG_SPINLOCK
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.lock = { \
+			.name = desc_name, \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.lock = { \
+			.name = desc_name, \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#else /* CONFIG_DEBUG_SPINLOCK */
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.lock = { \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.lock = { \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#endif /* CONFIG_DEBUG_SPINLOCK */
+
+#else /* CONFIG_SMP */
+
+/*
+ * Since the spinlocks are void on UP systems, we also need
+ * to have a special variant of interrupts-disabled spinlock
+ * macros which take this into account.
+ */
+
+#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
+	ASSERT_SPINLOCK(expr, NULL)
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#endif /* CONFIG_SMP */
+
+#define IRQ_SPINLOCK_INITIALIZE(lock_name) \
+	IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE(lock_name) \
+	IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
+
+extern void irq_spinlock_initialize(irq_spinlock_t *, const char *);
+extern void irq_spinlock_lock(irq_spinlock_t *, bool);
+extern void irq_spinlock_unlock(irq_spinlock_t *, bool);
+extern int irq_spinlock_trylock(irq_spinlock_t *);
+extern void irq_spinlock_pass(irq_spinlock_t *, irq_spinlock_t *);
+extern void irq_spinlock_exchange(irq_spinlock_t *, irq_spinlock_t *);
+extern bool irq_spinlock_locked(irq_spinlock_t *);
+
 #endif
 
-#endif
-
 /** @}
  */
