DECLARE_TRACEPOINT(rwmmio_post_read);
 
 void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                   unsigned long caller_addr);
+                   unsigned long caller_addr, unsigned long caller_addr0);
 void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                        unsigned long caller_addr);
+                        unsigned long caller_addr, unsigned long caller_addr0);
 void log_read_mmio(u8 width, const volatile void __iomem *addr,
-                  unsigned long caller_addr);
+                  unsigned long caller_addr, unsigned long caller_addr0);
 void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
-                       unsigned long caller_addr);
+                       unsigned long caller_addr, unsigned long caller_addr0);
 
 #else
 
 static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                                 unsigned long caller_addr) {}
+                                 unsigned long caller_addr, unsigned long caller_addr0) {}
 static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                                      unsigned long caller_addr) {}
+                                      unsigned long caller_addr, unsigned long caller_addr0) {}
 static inline void log_read_mmio(u8 width, const volatile void __iomem *addr,
-                                unsigned long caller_addr) {}
+                                unsigned long caller_addr, unsigned long caller_addr0) {}
 static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
-                                     unsigned long caller_addr) {}
+                                     unsigned long caller_addr, unsigned long caller_addr0) {}
 
 #endif /* CONFIG_TRACE_MMIO_ACCESS */
 
 {
        u8 val;
 
-       log_read_mmio(8, addr, _THIS_IP_);
+       log_read_mmio(8, addr, _THIS_IP_, _RET_IP_);
        __io_br();
        val = __raw_readb(addr);
        __io_ar(val);
-       log_post_read_mmio(val, 8, addr, _THIS_IP_);
+       log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u16 val;
 
-       log_read_mmio(16, addr, _THIS_IP_);
+       log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
        __io_br();
        val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
        __io_ar(val);
-       log_post_read_mmio(val, 16, addr, _THIS_IP_);
+       log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u32 val;
 
-       log_read_mmio(32, addr, _THIS_IP_);
+       log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
        __io_br();
        val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
        __io_ar(val);
-       log_post_read_mmio(val, 32, addr, _THIS_IP_);
+       log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u64 val;
 
-       log_read_mmio(64, addr, _THIS_IP_);
+       log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
        __io_br();
        val = __le64_to_cpu(__raw_readq(addr));
        __io_ar(val);
-       log_post_read_mmio(val, 64, addr, _THIS_IP_);
+       log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 #define writeb writeb
 static inline void writeb(u8 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 8, addr, _THIS_IP_);
+       log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
        __io_bw();
        __raw_writeb(value, addr);
        __io_aw();
-       log_post_write_mmio(value, 8, addr, _THIS_IP_);
+       log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writew writew
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 16, addr, _THIS_IP_);
+       log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
        __io_bw();
        __raw_writew((u16 __force)cpu_to_le16(value), addr);
        __io_aw();
-       log_post_write_mmio(value, 16, addr, _THIS_IP_);
+       log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writel writel
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 32, addr, _THIS_IP_);
+       log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
        __io_bw();
        __raw_writel((u32 __force)__cpu_to_le32(value), addr);
        __io_aw();
-       log_post_write_mmio(value, 32, addr, _THIS_IP_);
+       log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writeq writeq
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 64, addr, _THIS_IP_);
+       log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
        __io_bw();
        __raw_writeq(__cpu_to_le64(value), addr);
        __io_aw();
-       log_post_write_mmio(value, 64, addr, _THIS_IP_);
+       log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 #endif /* CONFIG_64BIT */
 {
        u8 val;
 
-       log_read_mmio(8, addr, _THIS_IP_);
+       log_read_mmio(8, addr, _THIS_IP_, _RET_IP_);
        val = __raw_readb(addr);
-       log_post_read_mmio(val, 8, addr, _THIS_IP_);
+       log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u16 val;
 
-       log_read_mmio(16, addr, _THIS_IP_);
+       log_read_mmio(16, addr, _THIS_IP_, _RET_IP_);
        val = __le16_to_cpu(__raw_readw(addr));
-       log_post_read_mmio(val, 16, addr, _THIS_IP_);
+       log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u32 val;
 
-       log_read_mmio(32, addr, _THIS_IP_);
+       log_read_mmio(32, addr, _THIS_IP_, _RET_IP_);
        val = __le32_to_cpu(__raw_readl(addr));
-       log_post_read_mmio(val, 32, addr, _THIS_IP_);
+       log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 {
        u64 val;
 
-       log_read_mmio(64, addr, _THIS_IP_);
+       log_read_mmio(64, addr, _THIS_IP_, _RET_IP_);
        val = __le64_to_cpu(__raw_readq(addr));
-       log_post_read_mmio(val, 64, addr, _THIS_IP_);
+       log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_);
        return val;
 }
 #endif
 #define writeb_relaxed writeb_relaxed
 static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 8, addr, _THIS_IP_);
+       log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
        __raw_writeb(value, addr);
-       log_post_write_mmio(value, 8, addr, _THIS_IP_);
+       log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writew_relaxed writew_relaxed
 static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 16, addr, _THIS_IP_);
+       log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
        __raw_writew(cpu_to_le16(value), addr);
-       log_post_write_mmio(value, 16, addr, _THIS_IP_);
+       log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writel_relaxed writel_relaxed
 static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 32, addr, _THIS_IP_);
+       log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
        __raw_writel(__cpu_to_le32(value), addr);
-       log_post_write_mmio(value, 32, addr, _THIS_IP_);
+       log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 #define writeq_relaxed writeq_relaxed
 static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
 {
-       log_write_mmio(value, 64, addr, _THIS_IP_);
+       log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
        __raw_writeq(__cpu_to_le64(value), addr);
-       log_post_write_mmio(value, 64, addr, _THIS_IP_);
+       log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);
 }
 #endif
 
 
 
 DECLARE_EVENT_CLASS(rwmmio_rw_template,
 
-       TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+       TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
+                volatile void __iomem *addr),
 
-       TP_ARGS(caller, val, width, addr),
+       TP_ARGS(caller, caller0, val, width, addr),
 
        TP_STRUCT__entry(
                __field(unsigned long, caller)
+               __field(unsigned long, caller0)
                __field(unsigned long, addr)
                __field(u64, val)
                __field(u8, width)
 
        TP_fast_assign(
                __entry->caller = caller;
+               __entry->caller0 = caller0;
                __entry->val = val;
                __entry->addr = (unsigned long)addr;
                __entry->width = width;
        ),
 
-       TP_printk("%pS width=%d val=%#llx addr=%#lx",
-               (void *)__entry->caller, __entry->width,
+       TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
+               (void *)__entry->caller0, (void *)__entry->caller, __entry->width,
                __entry->val, __entry->addr)
 );
 
 DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
-       TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
-       TP_ARGS(caller, val, width, addr)
+       TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
+                volatile void __iomem *addr),
+       TP_ARGS(caller, caller0, val, width, addr)
 );
 
 DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
-       TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
-       TP_ARGS(caller, val, width, addr)
+       TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
+                volatile void __iomem *addr),
+       TP_ARGS(caller, caller0, val, width, addr)
 );
 
 TRACE_EVENT(rwmmio_read,
 
-       TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
+       TP_PROTO(unsigned long caller, unsigned long caller0, u8 width,
+                const volatile void __iomem *addr),
 
-       TP_ARGS(caller, width, addr),
+       TP_ARGS(caller, caller0, width, addr),
 
        TP_STRUCT__entry(
                __field(unsigned long, caller)
+               __field(unsigned long, caller0)
                __field(unsigned long, addr)
                __field(u8, width)
        ),
 
        TP_fast_assign(
                __entry->caller = caller;
+               __entry->caller0 = caller0;
                __entry->addr = (unsigned long)addr;
                __entry->width = width;
        ),
 
-       TP_printk("%pS width=%d addr=%#lx",
-                (void *)__entry->caller, __entry->width, __entry->addr)
+       TP_printk("%pS -> %pS width=%d addr=%#lx",
+                (void *)__entry->caller0, (void *)__entry->caller, __entry->width, __entry->addr)
 );
 
 TRACE_EVENT(rwmmio_post_read,
 
-       TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
+       TP_PROTO(unsigned long caller, unsigned long caller0, u64 val, u8 width,
+                const volatile void __iomem *addr),
 
-       TP_ARGS(caller, val, width, addr),
+       TP_ARGS(caller, caller0, val, width, addr),
 
        TP_STRUCT__entry(
                __field(unsigned long, caller)
+               __field(unsigned long, caller0)
                __field(unsigned long, addr)
                __field(u64, val)
                __field(u8, width)
 
        TP_fast_assign(
                __entry->caller = caller;
+               __entry->caller0 = caller0;
                __entry->val = val;
                __entry->addr = (unsigned long)addr;
                __entry->width = width;
        ),
 
-       TP_printk("%pS width=%d val=%#llx addr=%#lx",
-                (void *)__entry->caller, __entry->width,
+       TP_printk("%pS -> %pS width=%d val=%#llx addr=%#lx",
+                (void *)__entry->caller0, (void *)__entry->caller, __entry->width,
                 __entry->val, __entry->addr)
 );
 
 
 
 #ifdef CONFIG_TRACE_MMIO_ACCESS
 void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                   unsigned long caller_addr)
+                   unsigned long caller_addr, unsigned long caller_addr0)
 {
-       trace_rwmmio_write(caller_addr, val, width, addr);
+       trace_rwmmio_write(caller_addr, caller_addr0, val, width, addr);
 }
 EXPORT_SYMBOL_GPL(log_write_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
 
 void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
-                        unsigned long caller_addr)
+                        unsigned long caller_addr, unsigned long caller_addr0)
 {
-       trace_rwmmio_post_write(caller_addr, val, width, addr);
+       trace_rwmmio_post_write(caller_addr, caller_addr0, val, width, addr);
 }
 EXPORT_SYMBOL_GPL(log_post_write_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
 
 void log_read_mmio(u8 width, const volatile void __iomem *addr,
-                  unsigned long caller_addr)
+                  unsigned long caller_addr, unsigned long caller_addr0)
 {
-       trace_rwmmio_read(caller_addr, width, addr);
+       trace_rwmmio_read(caller_addr, caller_addr0, width, addr);
 }
 EXPORT_SYMBOL_GPL(log_read_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
 
 void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
-                       unsigned long caller_addr)
+                       unsigned long caller_addr, unsigned long caller_addr0)
 {
-       trace_rwmmio_post_read(caller_addr, val, width, addr);
+       trace_rwmmio_post_read(caller_addr, caller_addr0, val, width, addr);
 }
 EXPORT_SYMBOL_GPL(log_post_read_mmio);
 EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);