--- /dev/null
+From 4932e2c3c716067f3580e1a9687bed9d751549e3 Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+Date: Tue, 11 Feb 2014 17:12:48 +0200
+Subject: drm/i915: add unregister callback to connector
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Imre Deak <imre.deak@intel.com>
+
+commit 4932e2c3c716067f3580e1a9687bed9d751549e3 upstream.
+
+Since
+
+commit d9255d57147e1dbcebdf6670409c2fa0ac3609e6
+Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Date: Thu Sep 26 20:05:59 2013 -0300
+
+it became clear that we need to separate the unload sequence into two
+parts:
+
+1. remove all interfaces through which new operations on some object
+ (crtc, encoder, connector) can be started and make sure all pending
+ operations are completed
+2. do the actual tear down of the internal representation of the above
+ objects
+
+The above commit achieved this separation for connectors by splitting
+out the sysfs removal part from the connector's destroy callback and
+doing this removal before calling drm_mode_config_cleanup() which does
+the actual tear-down of all the drm objects.
+
+Since we'll have to customize the interface removal part for different
+types of connectors in the upcoming patches, add a new unregister
+callback and move the interface removal part to it.
+
+No functional change.
+
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h | 1 +
+ drivers/gpu/drm/i915/intel_crt.c | 1 +
+ drivers/gpu/drm/i915/intel_display.c | 14 ++++++++++++--
+ drivers/gpu/drm/i915/intel_dp.c | 1 +
+ drivers/gpu/drm/i915/intel_drv.h | 8 ++++++++
+ drivers/gpu/drm/i915/intel_dsi.c | 1 +
+ drivers/gpu/drm/i915/intel_dvo.c | 1 +
+ drivers/gpu/drm/i915/intel_hdmi.c | 1 +
+ drivers/gpu/drm/i915/intel_lvds.c | 1 +
+ drivers/gpu/drm/i915/intel_sdvo.c | 1 +
+ drivers/gpu/drm/i915/intel_tv.c | 1 +
+ 11 files changed, 29 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -2426,6 +2426,7 @@ extern void intel_modeset_suspend_hw(str
+ extern void intel_modeset_init(struct drm_device *dev);
+ extern void intel_modeset_gem_init(struct drm_device *dev);
+ extern void intel_modeset_cleanup(struct drm_device *dev);
++extern void intel_connector_unregister(struct intel_connector *);
+ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
+ extern void intel_modeset_setup_hw_state(struct drm_device *dev,
+ bool force_restore);
+--- a/drivers/gpu/drm/i915/intel_crt.c
++++ b/drivers/gpu/drm/i915/intel_crt.c
+@@ -841,6 +841,7 @@ void intel_crt_init(struct drm_device *d
+ crt->base.get_hw_state = intel_crt_get_hw_state;
+ }
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -11368,6 +11368,14 @@ void intel_modeset_gem_init(struct drm_d
+ mutex_unlock(&dev->mode_config.mutex);
+ }
+
++void intel_connector_unregister(struct intel_connector *intel_connector)
++{
++ struct drm_connector *connector = &intel_connector->base;
++
++ intel_panel_destroy_backlight(connector);
++ drm_sysfs_connector_remove(connector);
++}
++
+ void intel_modeset_cleanup(struct drm_device *dev)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -11412,8 +11420,10 @@ void intel_modeset_cleanup(struct drm_de
+
+ /* destroy the backlight and sysfs files before encoders/connectors */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+- intel_panel_destroy_backlight(connector);
+- drm_sysfs_connector_remove(connector);
++ struct intel_connector *intel_connector;
++
++ intel_connector = to_intel_connector(connector);
++ intel_connector->unregister(intel_connector);
+ }
+
+ drm_mode_config_cleanup(dev);
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -3686,6 +3686,7 @@ intel_dp_init_connector(struct intel_dig
+ intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+ else
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
+ if (HAS_DDI(dev)) {
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -187,6 +187,14 @@ struct intel_connector {
+ * and active (i.e. dpms ON state). */
+ bool (*get_hw_state)(struct intel_connector *);
+
++ /*
++ * Removes all interfaces through which the connector is accessible
++ * - like sysfs, debugfs entries -, so that no new operations can be
++ * started on the connector. Also makes sure all currently pending
++ * operations finish before returing.
++ */
++ void (*unregister)(struct intel_connector *);
++
+ /* Panel info for eDP and LVDS */
+ struct intel_panel panel;
+
+--- a/drivers/gpu/drm/i915/intel_dsi.c
++++ b/drivers/gpu/drm/i915/intel_dsi.c
+@@ -586,6 +586,7 @@ bool intel_dsi_init(struct drm_device *d
+ intel_encoder->get_config = intel_dsi_get_config;
+
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ for (i = 0; i < ARRAY_SIZE(intel_dsi_devices); i++) {
+ dsi = &intel_dsi_devices[i];
+--- a/drivers/gpu/drm/i915/intel_dvo.c
++++ b/drivers/gpu/drm/i915/intel_dvo.c
+@@ -477,6 +477,7 @@ void intel_dvo_init(struct drm_device *d
+ intel_encoder->compute_config = intel_dvo_compute_config;
+ intel_encoder->mode_set = intel_dvo_mode_set;
+ intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ /* Now, try to find a controller */
+ for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
+--- a/drivers/gpu/drm/i915/intel_hdmi.c
++++ b/drivers/gpu/drm/i915/intel_hdmi.c
+@@ -1262,6 +1262,7 @@ void intel_hdmi_init_connector(struct in
+ intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+ else
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ intel_hdmi_add_properties(intel_hdmi, connector);
+
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -957,6 +957,7 @@ void intel_lvds_init(struct drm_device *
+ intel_encoder->get_hw_state = intel_lvds_get_hw_state;
+ intel_encoder->get_config = intel_lvds_get_config;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ intel_connector_attach_encoder(intel_connector, intel_encoder);
+ intel_encoder->type = INTEL_OUTPUT_LVDS;
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -2397,6 +2397,7 @@ intel_sdvo_connector_init(struct intel_s
+ connector->base.base.doublescan_allowed = 0;
+ connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
++ connector->base.unregister = intel_connector_unregister;
+
+ intel_connector_attach_encoder(&connector->base, &encoder->base);
+ drm_sysfs_connector_add(&connector->base.base);
+--- a/drivers/gpu/drm/i915/intel_tv.c
++++ b/drivers/gpu/drm/i915/intel_tv.c
+@@ -1639,6 +1639,7 @@ intel_tv_init(struct drm_device *dev)
+ intel_encoder->disable = intel_disable_tv;
+ intel_encoder->get_hw_state = intel_tv_get_hw_state;
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
++ intel_connector->unregister = intel_connector_unregister;
+
+ intel_connector_attach_encoder(intel_connector, intel_encoder);
+ intel_encoder->type = INTEL_OUTPUT_TVOUT;
--- /dev/null
+From 80f65de3c9b8101c1613fa82df500ba6a099a11c Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+Date: Tue, 11 Feb 2014 17:12:49 +0200
+Subject: drm/i915: dp: fix order of dp aux i2c device cleanup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Imre Deak <imre.deak@intel.com>
+
+commit 80f65de3c9b8101c1613fa82df500ba6a099a11c upstream.
+
+Atm we set the parent of the dp i2c device to be the correspondig
+connector device. During driver cleanup we first remove the connector
+device through intel_modeset_cleanup()->drm_sysfs_connector_remove() and
+only after that the i2c device through the encoder's destroy callback.
+This order is not supported by the device core and we'll get a warning,
+see the below bugzilla ticket. The proper order is to remove first any
+child device and only then the parent device.
+
+The first part of the fix changes the i2c device's parent to be the drm
+device. Its logical owner is not the connector anyway, but the encoder.
+Since the encoder doesn't have a device object, the next best choice is
+the drm device. This is the same what we do in the case of the sdvo i2c
+device and what the nouveau driver does.
+
+The second part creates a symlink in the connector's sysfs directory
+pointing to the i2c device. This is so, that we keep the current ABI,
+which also makes sense in case someone wants to look up the i2c device
+belonging to a specific connector.
+
+Reference: http://lists.freedesktop.org/archives/intel-gfx/2014-January/038782.html
+Reference: http://lists.freedesktop.org/archives/intel-gfx/2014-February/039427.html
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70523
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_dp.c | 24 ++++++++++++++++++++++--
+ 1 file changed, 22 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -744,6 +744,16 @@ out:
+ return ret;
+ }
+
++static void
++intel_dp_connector_unregister(struct intel_connector *intel_connector)
++{
++ struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
++
++ sysfs_remove_link(&intel_connector->base.kdev->kobj,
++ intel_dp->adapter.dev.kobj.name);
++ intel_connector_unregister(intel_connector);
++}
++
+ static int
+ intel_dp_i2c_init(struct intel_dp *intel_dp,
+ struct intel_connector *intel_connector, const char *name)
+@@ -761,9 +771,19 @@ intel_dp_i2c_init(struct intel_dp *intel
+ strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
+ intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
+ intel_dp->adapter.algo_data = &intel_dp->algo;
+- intel_dp->adapter.dev.parent = intel_connector->base.kdev;
++ intel_dp->adapter.dev.parent = intel_connector->base.dev->dev;
+
+ ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
++ if (ret < 0)
++ return ret;
++
++ ret = sysfs_create_link(&intel_connector->base.kdev->kobj,
++ &intel_dp->adapter.dev.kobj,
++ intel_dp->adapter.dev.kobj.name);
++
++ if (ret < 0)
++ i2c_del_adapter(&intel_dp->adapter);
++
+ return ret;
+ }
+
+@@ -3686,7 +3706,7 @@ intel_dp_init_connector(struct intel_dig
+ intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+ else
+ intel_connector->get_hw_state = intel_connector_get_hw_state;
+- intel_connector->unregister = intel_connector_unregister;
++ intel_connector->unregister = intel_dp_connector_unregister;
+
+ intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
+ if (HAS_DDI(dev)) {
--- /dev/null
+From ecd15dd7e45f3683fa8142b9f2c015dfaa0c243d Mon Sep 17 00:00:00 2001
+From: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
+Date: Sun, 4 May 2014 13:35:37 +0200
+Subject: netfilter: nfnetlink: Fix use after free when it fails to process batch
+
+From: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
+
+commit ecd15dd7e45f3683fa8142b9f2c015dfaa0c243d upstream.
+
+This bug manifests when calling the nft command line tool without
+nf_tables kernel support.
+
+kernel message:
+[ 44.071555] Netfilter messages via NETLINK v0.30.
+[ 44.072253] BUG: unable to handle kernel NULL pointer dereference at 0000000000000119
+[ 44.072264] IP: [<ffffffff8171db1f>] netlink_getsockbyportid+0xf/0x70
+[ 44.072272] PGD 7f2b74067 PUD 7f2b73067 PMD 0
+[ 44.072277] Oops: 0000 [#1] SMP
+[...]
+[ 44.072369] Call Trace:
+[ 44.072373] [<ffffffff8171fd81>] netlink_unicast+0x91/0x200
+[ 44.072377] [<ffffffff817206c9>] netlink_ack+0x99/0x110
+[ 44.072381] [<ffffffffa004b951>] nfnetlink_rcv+0x3c1/0x408 [nfnetlink]
+[ 44.072385] [<ffffffff8171fde3>] netlink_unicast+0xf3/0x200
+[ 44.072389] [<ffffffff817201ef>] netlink_sendmsg+0x2ff/0x740
+[ 44.072394] [<ffffffff81044752>] ? __mmdrop+0x62/0x90
+[ 44.072398] [<ffffffff816dafdb>] sock_sendmsg+0x8b/0xc0
+[ 44.072403] [<ffffffff812f1af5>] ? copy_user_enhanced_fast_string+0x5/0x10
+[ 44.072406] [<ffffffff816dbb6c>] ? move_addr_to_kernel+0x2c/0x50
+[ 44.072410] [<ffffffff816db423>] ___sys_sendmsg+0x3c3/0x3d0
+[ 44.072415] [<ffffffff811301ba>] ? handle_mm_fault+0xa9a/0xc60
+[ 44.072420] [<ffffffff811362d6>] ? mmap_region+0x166/0x5a0
+[ 44.072424] [<ffffffff817da84c>] ? __do_page_fault+0x1dc/0x510
+[ 44.072428] [<ffffffff812b8b2c>] ? apparmor_capable+0x1c/0x60
+[ 44.072435] [<ffffffff817d6e9a>] ? _raw_spin_unlock_bh+0x1a/0x20
+[ 44.072439] [<ffffffff816dfc86>] ? release_sock+0x106/0x150
+[ 44.072443] [<ffffffff816dc212>] __sys_sendmsg+0x42/0x80
+[ 44.072446] [<ffffffff816dc262>] SyS_sendmsg+0x12/0x20
+[ 44.072450] [<ffffffff817df616>] system_call_fastpath+0x1a/0x1f
+
+Signed-off-by: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nfnetlink.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -248,15 +248,15 @@ replay:
+ #endif
+ {
+ nfnl_unlock(subsys_id);
+- kfree_skb(nskb);
+- return netlink_ack(skb, nlh, -EOPNOTSUPP);
++ netlink_ack(skb, nlh, -EOPNOTSUPP);
++ return kfree_skb(nskb);
+ }
+ }
+
+ if (!ss->commit || !ss->abort) {
+ nfnl_unlock(subsys_id);
+- kfree_skb(nskb);
+- return netlink_ack(skb, nlh, -EOPNOTSUPP);
++ netlink_ack(skb, nlh, -EOPNOTSUPP);
++ return kfree_skb(skb);
+ }
+
+ while (skb->len >= nlmsg_total_size(0)) {