__ftrace_make_nop(struct module *mod,
                  struct dyn_ftrace *rec, unsigned long addr)
 {
-       /* Ignore modules for PPC32 (for now) */
+       unsigned char replaced[MCOUNT_INSN_SIZE];
+       unsigned int *op = (unsigned *)&replaced;
+       unsigned char jmp[8];
+       unsigned int *ptr = (unsigned int *)&jmp;
+       unsigned long ip = rec->ip;
+       unsigned long tramp;
+       int offset;
+
+       if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+               return -EFAULT;
+
+       /* Make sure that that this is still a 24bit jump */
+       if (!is_bl_op(*op)) {
+               printk(KERN_ERR "Not expected bl: opcode is %x\n", *op);
+               return -EINVAL;
+       }
+
+       /* lets find where the pointer goes */
+       tramp = find_bl_target(ip, *op);
+
+       /*
+        * On PPC32 the trampoline looks like:
+        * lis r11,sym@ha
+        * addi r11,r11,sym@l
+        * mtctr r11
+        * bctr
+        */
+
+       DEBUGP("ip:%lx jumps to %lx", ip, tramp);
+
+       /* Find where the trampoline jumps to */
+       if (probe_kernel_read(jmp, (void *)tramp, 8)) {
+               printk(KERN_ERR "Failed to read %lx\n", tramp);
+               return -EFAULT;
+       }
+
+       DEBUGP(" %08x %08x ", ptr[0], ptr[1]);
+
+       tramp = (ptr[1] & 0xffff) |
+               ((ptr[0] & 0xffff) << 16);
+       if (tramp & 0x8000)
+               tramp -= 0x10000;
+
+       DEBUGP(" %x ", tramp);
+
+       if (tramp != addr) {
+               printk(KERN_ERR
+                      "Trampoline location %08lx does not match addr\n",
+                      tramp);
+               return -EINVAL;
+       }
+
+       op[0] = PPC_NOP_INSTR;
+
+       if (probe_kernel_write((void *)ip, replaced, MCOUNT_INSN_SIZE))
+               return -EPERM;
+
        return 0;
 }
 #endif /* PPC64 */
                return ftrace_modify_code(ip, old, new);
        }
 
-#ifdef CONFIG_PPC64
        /*
         * Out of range jumps are called from modules.
         * We should either already have a pointer to the module
                /* nothing to do if mod == rec->arch.mod */
        } else
                mod = rec->arch.mod;
-#endif /* CONFIG_PPC64 */
 
        return __ftrace_make_nop(mod, rec, addr);
 
 static int
 __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
-       /* PPC32 ignores modules for now */
+       unsigned char replaced[MCOUNT_INSN_SIZE];
+       unsigned int *op = (unsigned *)&replaced;
+       unsigned long ip = rec->ip;
+       unsigned long offset;
+
+       /* read where this goes */
+       if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+               return -EFAULT;
+
+       /* It should be pointing to a nop */
+       if (op[0] != PPC_NOP_INSTR) {
+               printk(KERN_ERR "Expected NOP but have %x\n", op[0]);
+               return -EINVAL;
+       }
+
+       /* If we never set up a trampoline to ftrace_caller, then bail */
+       if (!rec->arch.mod->arch.tramp) {
+               printk(KERN_ERR "No ftrace trampoline\n");
+               return -EINVAL;
+       }
+
+       /* now calculate a jump to the ftrace caller trampoline */
+       offset = rec->arch.mod->arch.tramp - ip;
+
+       if (test_offset(offset)) {
+               printk(KERN_ERR "REL24 %li out of range!\n",
+                      (long int)offset);
+               return -EINVAL;
+       }
+
+       /* Set to "bl addr" */
+       op[0] = branch_offset(offset);
+
+       DEBUGP("write to %lx\n", rec->ip);
+
+       if (probe_kernel_write((void *)ip, replaced, MCOUNT_INSN_SIZE))
+               return -EPERM;
+
        return 0;
 }
 #endif /* CONFIG_PPC64 */
                return ftrace_modify_code(ip, old, new);
        }
 
-#ifdef CONFIG_PPC64
        /*
         * Out of range jumps are called from modules.
         * Being that we are converting from nop, it had better
                printk(KERN_ERR "No module loaded\n");
                return -EINVAL;
        }
-#endif
 
        return __ftrace_make_call(rec, addr);
 }