return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
 }
 
+#ifdef CONFIG_PPC64
+static __inline__ unsigned long clear_bit_unlock_return_word(int nr,
+                                               volatile unsigned long *addr)
+{
+       unsigned long old, t;
+       unsigned long *p = (unsigned long *)addr + BIT_WORD(nr);
+       unsigned long mask = BIT_MASK(nr);
+
+       __asm__ __volatile__ (
+       PPC_RELEASE_BARRIER
+"1:"   PPC_LLARX(%0,0,%3,0) "\n"
+       "andc %1,%0,%2\n"
+       PPC405_ERR77(0,%3)
+       PPC_STLCX "%1,0,%3\n"
+       "bne- 1b\n"
+       : "=&r" (old), "=&r" (t)
+       : "r" (mask), "r" (p)
+       : "cc", "memory");
+
+       return old;
+}
+
+/* This is a special function for mm/filemap.c */
+#define clear_bit_unlock_is_negative_byte(nr, addr)                    \
+       (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(PG_waiters))
+
+#endif /* CONFIG_PPC64 */
+
 #include <asm-generic/bitops/non-atomic.h>
 
 static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)