--- /dev/null
+From 45959ee7aa645815a5ce303a0ea1e48a21e67c6a Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Mon, 12 Dec 2011 15:22:41 -0500
+Subject: ftrace: Do not function trace inlined functions
+
+From: Steven Rostedt <srostedt@redhat.com>
+
+commit 45959ee7aa645815a5ce303a0ea1e48a21e67c6a upstream.
+
+When gcc inlines a function, it does not mark it with the mcount
+prologue, which in turn means that inlined functions are not traced
+by the function tracer. But if CONFIG_OPTIMIZE_INLINING is set, then
+gcc is allowed not to inline a function that is marked inline.
+
+Depending on the options and the compiler, a function may or may
+not be traced by the function tracer, depending on whether gcc
+decides to inline a function or not. This has caused several
+problems in the pass becaues gcc is not always consistent with
+what it decides to inline between different gcc versions.
+
+Some places should not be traced (like paravirt native_* functions)
+and these are mostly marked as inline. When gcc decides not to
+inline the function, and if that function should not be traced, then
+the ftrace function tracer will suddenly break when it use to work
+fine. This becomes even harder to debug when different versions of
+gcc will not inline that function, making the same kernel and config
+work for some gcc versions and not work for others.
+
+By making all functions marked inline to not be traced will remove
+the ambiguity that gcc adds when it comes to tracing functions marked
+inline. All gcc versions will be consistent with what functions are
+traced and having volatile working code will be removed.
+
+Note, only the inline macro when CONFIG_OPTIMIZE_INLINING is set needs
+to have notrace added, as the attribute __always_inline will force
+the function to be inlined and then not traced.
+
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/compiler-gcc.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -50,6 +50,11 @@
+ # define inline inline __attribute__((always_inline))
+ # define __inline__ __inline__ __attribute__((always_inline))
+ # define __inline __inline __attribute__((always_inline))
++#else
++/* A lot of inline functions can cause havoc with function tracing */
++# define inline inline notrace
++# define __inline__ __inline__ notrace
++# define __inline __inline notrace
+ #endif
+
+ #define __deprecated __attribute__((deprecated))
+++ /dev/null
-From 0f9df939385527049c8062a099fbfa1479fe7ce0 Mon Sep 17 00:00:00 2001
-From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Date: Mon, 22 Oct 2012 22:15:05 +0200
-Subject: usb: gadget: uvc: fix error path in uvc_function_bind()
-
-From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-
-commit 0f9df939385527049c8062a099fbfa1479fe7ce0 upstream.
-
-The "video->minor = -1" assigment is done in V4L2 by
-video_register_device() so it is removed here.
-Now. uvc_function_bind() calls in error case uvc_function_unbind() for
-cleanup. The problem is that uvc_function_unbind() frees the uvc struct
-and uvc_bind_config() does as well in error case of usb_add_function().
-Removing kfree() in usb_add_function() would make the patch smaller but
-it would look odd because the new allocated memory is not cleaned up.
-However it is not guaranteed that if we call usb_add_function() we also
-get to the bind function.
-Therefore the patch extracts the conditional cleanup from
-uvc_function_unbind() applies to uvc_function_bind().
-uvc_function_unbind() now contains only the complete cleanup which is
-required once everything has been registrated.
-
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Cc: Bhupesh Sharma <bhupesh.sharma@st.com>
-Signed-off-by: Felipe Balbi <balbi@ti.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/gadget/f_uvc.c | 39 +++++++++++++++++++++------------------
- 1 file changed, 21 insertions(+), 18 deletions(-)
-
---- a/drivers/usb/gadget/f_uvc.c
-+++ b/drivers/usb/gadget/f_uvc.c
-@@ -334,7 +334,6 @@ uvc_register_video(struct uvc_device *uv
- return -ENOMEM;
-
- video->parent = &cdev->gadget->dev;
-- video->minor = -1;
- video->fops = &uvc_v4l2_fops;
- video->release = video_device_release;
- strncpy(video->name, cdev->gadget->name, sizeof(video->name));
-@@ -461,23 +460,12 @@ uvc_function_unbind(struct usb_configura
-
- INFO(cdev, "uvc_function_unbind\n");
-
-- if (uvc->vdev) {
-- if (uvc->vdev->minor == -1)
-- video_device_release(uvc->vdev);
-- else
-- video_unregister_device(uvc->vdev);
-- uvc->vdev = NULL;
-- }
--
-- if (uvc->control_ep)
-- uvc->control_ep->driver_data = NULL;
-- if (uvc->video.ep)
-- uvc->video.ep->driver_data = NULL;
-+ video_unregister_device(uvc->vdev);
-+ uvc->control_ep->driver_data = NULL;
-+ uvc->video.ep->driver_data = NULL;
-
-- if (uvc->control_req) {
-- usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
-- kfree(uvc->control_buf);
-- }
-+ usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
-+ kfree(uvc->control_buf);
-
- kfree(f->descriptors);
- kfree(f->hs_descriptors);
-@@ -562,7 +550,22 @@ uvc_function_bind(struct usb_configurati
- return 0;
-
- error:
-- uvc_function_unbind(c, f);
-+ if (uvc->vdev)
-+ video_device_release(uvc->vdev);
-+
-+ if (uvc->control_ep)
-+ uvc->control_ep->driver_data = NULL;
-+ if (uvc->video.ep)
-+ uvc->video.ep->driver_data = NULL;
-+
-+ if (uvc->control_req) {
-+ usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
-+ kfree(uvc->control_buf);
-+ }
-+
-+ kfree(f->descriptors);
-+ kfree(f->hs_descriptors);
-+ kfree(f->ss_descriptors);
- return ret;
- }
-