@@ -50,14 +50,34 @@ extern unsigned int __mfdcr(unsigned int reg);
static inline unsigned int mfdcrx(unsigned int reg)
{
unsigned int ret;
- asm volatile(".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
+ asm volatile(
+#ifdef CONFIG_PPC_47x
+ /*
+ * Workaround: move reg to an spr prior to mfdcrx instruction
+ */
+ /* __stringify(BEGIN_FTR_SECTION) */
+ "mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;"
+ /* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */
+#endif
+ ".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
: "=r" (ret) : "r" (reg));
return ret;
}
static inline void mtdcrx(unsigned int reg, unsigned int val)
{
- asm volatile(".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
+ asm volatile(
+#ifdef CONFIG_PPC_47x
+ /*
+ * Workaround: move reg to an spr prior to mtdcrx instruction.
+ * (Would love to get the FTR_SECTION macros working for
+ * inlined assembler -- shaggy)
+ */
+ /* __stringify(BEGIN_FTR_SECTION) */
+ "mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;"
+ /* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */
+#endif
+ ".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
: : "r" (val), "r" (reg));
}