]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 17:03:15 +0000 (19:03 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 May 2017 17:03:15 +0000 (19:03 +0200)
added patches:
cdc-acm-fix-possible-invalid-access-when-processing-notification.patch
cxl-force-context-lock-during-eeh-flow.patch
cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch
drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch
drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch
drm-amdgpu-make-display-watermark-calculations-more-accurate.patch
drm-nouveau-kms-nv50-fix-source-rect-only-plane-updates.patch
drm-nouveau-kms-nv50-skip-core-channel-cursor-update-on-position-only-changes.patch
drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch
drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch
drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch
drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch
drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch
drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch
gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch
ibmvscsis-do-not-send-aborted-task-response.patch
iio-bmp280-core.c-fix-error-in-humidity-calculation.patch
iio-dac-ad7303-fix-channel-description.patch
iio-stm32-trigger-fix-sampling_frequency-read.patch
of-fdt-add-missing-allocation-failure-check.patch
of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch
of-fix-sparse-warning-in-of_pci_range_parser_one.patch
ohci-pci-add-qemu-quirk.patch
proc-fix-unbalanced-hard-link-numbers.patch
scsi-lpfc-fix-panic-on-bfs-configuration.patch

26 files changed:
queue-4.11/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch [new file with mode: 0644]
queue-4.11/cxl-force-context-lock-during-eeh-flow.patch [new file with mode: 0644]
queue-4.11/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch [new file with mode: 0644]
queue-4.11/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch [new file with mode: 0644]
queue-4.11/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch [new file with mode: 0644]
queue-4.11/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-kms-nv50-fix-source-rect-only-plane-updates.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-kms-nv50-skip-core-channel-cursor-update-on-position-only-changes.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch [new file with mode: 0644]
queue-4.11/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch [new file with mode: 0644]
queue-4.11/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch [new file with mode: 0644]
queue-4.11/ibmvscsis-do-not-send-aborted-task-response.patch [new file with mode: 0644]
queue-4.11/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch [new file with mode: 0644]
queue-4.11/iio-dac-ad7303-fix-channel-description.patch [new file with mode: 0644]
queue-4.11/iio-stm32-trigger-fix-sampling_frequency-read.patch [new file with mode: 0644]
queue-4.11/of-fdt-add-missing-allocation-failure-check.patch [new file with mode: 0644]
queue-4.11/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch [new file with mode: 0644]
queue-4.11/of-fix-sparse-warning-in-of_pci_range_parser_one.patch [new file with mode: 0644]
queue-4.11/ohci-pci-add-qemu-quirk.patch [new file with mode: 0644]
queue-4.11/proc-fix-unbalanced-hard-link-numbers.patch [new file with mode: 0644]
queue-4.11/scsi-lpfc-fix-panic-on-bfs-configuration.patch [new file with mode: 0644]
queue-4.11/series

diff --git a/queue-4.11/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch b/queue-4.11/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch
new file mode 100644 (file)
index 0000000..258d02a
--- /dev/null
@@ -0,0 +1,52 @@
+From 1bb9914e1730417d530de9ed37e59efdc647146b Mon Sep 17 00:00:00 2001
+From: Tobias Herzog <t-herzog@gmx.de>
+Date: Thu, 30 Mar 2017 22:15:10 +0200
+Subject: cdc-acm: fix possible invalid access when processing notification
+
+From: Tobias Herzog <t-herzog@gmx.de>
+
+commit 1bb9914e1730417d530de9ed37e59efdc647146b upstream.
+
+Notifications may only be 8 bytes long. Accessing the 9th and
+10th byte of unimplemented/unknown notifications may be insecure.
+Also check the length of known notifications before accessing anything
+behind the 8th byte.
+
+Signed-off-by: Tobias Herzog <t-herzog@gmx.de>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -323,6 +323,12 @@ static void acm_ctrl_irq(struct urb *urb
+               break;
+       case USB_CDC_NOTIFY_SERIAL_STATE:
++              if (le16_to_cpu(dr->wLength) != 2) {
++                      dev_dbg(&acm->control->dev,
++                              "%s - malformed serial state\n", __func__);
++                      break;
++              }
++
+               newctrl = get_unaligned_le16(data);
+               if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
+@@ -359,11 +365,10 @@ static void acm_ctrl_irq(struct urb *urb
+       default:
+               dev_dbg(&acm->control->dev,
+-                      "%s - unknown notification %d received: index %d "
+-                      "len %d data0 %d data1 %d\n",
++                      "%s - unknown notification %d received: index %d len %d\n",
+                       __func__,
+-                      dr->bNotificationType, dr->wIndex,
+-                      dr->wLength, data[0], data[1]);
++                      dr->bNotificationType, dr->wIndex, dr->wLength);
++
+               break;
+       }
+ exit:
diff --git a/queue-4.11/cxl-force-context-lock-during-eeh-flow.patch b/queue-4.11/cxl-force-context-lock-during-eeh-flow.patch
new file mode 100644 (file)
index 0000000..dd3b9b9
--- /dev/null
@@ -0,0 +1,95 @@
+From ea9a26d117cf0637c71d3e0076f4a124bf5859df Mon Sep 17 00:00:00 2001
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Date: Thu, 27 Apr 2017 10:53:25 +0530
+Subject: cxl: Force context lock during EEH flow
+
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+
+commit ea9a26d117cf0637c71d3e0076f4a124bf5859df upstream.
+
+During an eeh event when the cxl card is fenced and card sysfs attr
+perst_reloads_same_image is set following warning message is seen in the
+kernel logs:
+
+  Adapter context unlocked with 0 active contexts
+  ------------[ cut here ]------------
+  WARNING: CPU: 12 PID: 627 at
+  ../drivers/misc/cxl/main.c:325 cxl_adapter_context_unlock+0x60/0x80 [cxl]
+
+Even though this warning is harmless, it clutters the kernel log
+during an eeh event. This warning is triggered as the EEH callback
+cxl_pci_error_detected doesn't obtain a context-lock before forcibly
+detaching all active context and when context-lock is released during
+call to cxl_configure_adapter from cxl_pci_slot_reset, a warning in
+cxl_adapter_context_unlock is triggered.
+
+To fix this warning, we acquire the adapter context-lock via
+cxl_adapter_context_lock() in the eeh callback
+cxl_pci_error_detected() once all the virtual AFU PHBs are notified
+and their contexts detached. The context-lock is released in
+cxl_pci_slot_reset() after the adapter is successfully reconfigured
+and before the we call the slot_reset callback on slice attached
+device-drivers.
+
+Fixes: 70b565bbdb91 ("cxl: Prevent adapter reset if an active context exists")
+Reported-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Reviewed-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
+Tested-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/cxl/pci.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1496,8 +1496,6 @@ static int cxl_configure_adapter(struct
+       if ((rc = cxl_native_register_psl_err_irq(adapter)))
+               goto err;
+-      /* Release the context lock as adapter is configured */
+-      cxl_adapter_context_unlock(adapter);
+       return 0;
+ err:
+@@ -1596,6 +1594,9 @@ static struct cxl *cxl_pci_init_adapter(
+       if ((rc = cxl_sysfs_adapter_add(adapter)))
+               goto err_put1;
++      /* Release the context lock as adapter is configured */
++      cxl_adapter_context_unlock(adapter);
++
+       return adapter;
+ err_put1:
+@@ -1895,6 +1896,13 @@ static pci_ers_result_t cxl_pci_error_de
+               cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
+               pci_deconfigure_afu(afu);
+       }
++
++      /* should take the context lock here */
++      if (cxl_adapter_context_lock(adapter) != 0)
++              dev_warn(&adapter->dev,
++                       "Couldn't take context lock with %d active-contexts\n",
++                       atomic_read(&adapter->contexts_num));
++
+       cxl_deconfigure_adapter(adapter);
+       return result;
+@@ -1913,6 +1921,13 @@ static pci_ers_result_t cxl_pci_slot_res
+       if (cxl_configure_adapter(adapter, pdev))
+               goto err;
++      /*
++       * Unlock context activation for the adapter. Ideally this should be
++       * done in cxl_pci_resume but cxlflash module tries to activate the
++       * master context as part of slot_reset callback.
++       */
++      cxl_adapter_context_unlock(adapter);
++
+       for (i = 0; i < adapter->slices; i++) {
+               afu = adapter->afu[i];
diff --git a/queue-4.11/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch b/queue-4.11/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch
new file mode 100644 (file)
index 0000000..89f9a96
--- /dev/null
@@ -0,0 +1,68 @@
+From 4f58f0bf155e87dda31a3088b1e107fa9dd79f0e Mon Sep 17 00:00:00 2001
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Date: Thu, 27 Apr 2017 10:58:22 +0530
+Subject: cxl: Route eeh events to all drivers in cxl_pci_error_detected()
+
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+
+commit 4f58f0bf155e87dda31a3088b1e107fa9dd79f0e upstream.
+
+Fix a boundary condition where in some cases an eeh event that results
+in card reset isn't passed on to a driver attached to the virtual PCI
+device associated with a slice. This will happen in case when a slice
+attached device driver returns a value other than
+PCI_ERS_RESULT_NEED_RESET from the eeh error_detected() callback. This
+would result in an early return from cxl_pci_error_detected() and
+other drivers attached to other AFUs on the card wont be notified.
+
+The patch fixes this by making sure that all slice attached
+device-drivers are notified and the return values from
+error_detected() callback are aggregated in a scheme where request for
+'disconnect' trumps all and 'none' trumps 'need_reset'.
+
+Fixes: 9e8df8a21963 ("cxl: EEH support")
+Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/cxl/pci.c |   15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1782,7 +1782,7 @@ static pci_ers_result_t cxl_pci_error_de
+ {
+       struct cxl *adapter = pci_get_drvdata(pdev);
+       struct cxl_afu *afu;
+-      pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET;
++      pci_ers_result_t result = PCI_ERS_RESULT_NEED_RESET, afu_result;
+       int i;
+       /* At this point, we could still have an interrupt pending.
+@@ -1886,15 +1886,18 @@ static pci_ers_result_t cxl_pci_error_de
+       for (i = 0; i < adapter->slices; i++) {
+               afu = adapter->afu[i];
+-              result = cxl_vphb_error_detected(afu, state);
+-
+-              /* Only continue if everyone agrees on NEED_RESET */
+-              if (result != PCI_ERS_RESULT_NEED_RESET)
+-                      return result;
++              afu_result = cxl_vphb_error_detected(afu, state);
+               cxl_context_detach_all(afu);
+               cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
+               pci_deconfigure_afu(afu);
++
++              /* Disconnect trumps all, NONE trumps NEED_RESET */
++              if (afu_result == PCI_ERS_RESULT_DISCONNECT)
++                      result = PCI_ERS_RESULT_DISCONNECT;
++              else if ((afu_result == PCI_ERS_RESULT_NONE) &&
++                       (result == PCI_ERS_RESULT_NEED_RESET))
++                      result = PCI_ERS_RESULT_NONE;
+       }
+       /* should take the context lock here */
diff --git a/queue-4.11/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch b/queue-4.11/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch
new file mode 100644 (file)
index 0000000..6ffd6d4
--- /dev/null
@@ -0,0 +1,51 @@
+From effaf848b957fbf72a3b6a1ad87f5e031eda0b75 Mon Sep 17 00:00:00 2001
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+Date: Mon, 24 Apr 2017 01:02:46 +0200
+Subject: drm/amdgpu: Add missing lb_vblank_lead_lines setup to DCE-6 path.
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+commit effaf848b957fbf72a3b6a1ad87f5e031eda0b75 upstream.
+
+This apparently got lost when implementing the new DCE-6 support
+and would cause failures in pageflip scheduling and timestamping.
+
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/dce_v6_0.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+@@ -979,7 +979,7 @@ static void dce_v6_0_program_watermarks(
+       u32 priority_a_mark = 0, priority_b_mark = 0;
+       u32 priority_a_cnt = PRIORITY_OFF;
+       u32 priority_b_cnt = PRIORITY_OFF;
+-      u32 tmp, arb_control3;
++      u32 tmp, arb_control3, lb_vblank_lead_lines = 0;
+       fixed20_12 a, b, c;
+       if (amdgpu_crtc->base.enabled && num_heads && mode) {
+@@ -1091,6 +1091,8 @@ static void dce_v6_0_program_watermarks(
+               c.full = dfixed_div(c, a);
+               priority_b_mark = dfixed_trunc(c);
+               priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
++
++              lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
+       }
+       /* select wm A */
+@@ -1120,6 +1122,9 @@ static void dce_v6_0_program_watermarks(
+       /* save values for DPM */
+       amdgpu_crtc->line_time = line_time;
+       amdgpu_crtc->wm_high = latency_watermark_a;
++
++      /* Save number of lines the linebuffer leads before the scanout */
++      amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines;
+ }
+ /* watermark setup */
diff --git a/queue-4.11/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch b/queue-4.11/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch
new file mode 100644 (file)
index 0000000..eecc3b1
--- /dev/null
@@ -0,0 +1,150 @@
+From e190ed1ea7458e446230de4113cc5d53b8dc4ec8 Mon Sep 17 00:00:00 2001
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+Date: Wed, 29 Mar 2017 22:09:12 +0200
+Subject: drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations.
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+commit e190ed1ea7458e446230de4113cc5d53b8dc4ec8 upstream.
+
+At dot clocks > approx. 250 Mhz, some of these calcs will overflow and
+cause miscalculation of latency watermarks, and for some overflows also
+divide-by-zero driver crash ("divide error: 0000 [#1] PREEMPT SMP" in
+"dce_v10_0_latency_watermark+0x12d/0x190").
+
+This zero-divide happened, e.g., on AMD Tonga Pro under DCE-10,
+on a Displayport panel when trying to set a video mode of 2560x1440
+at 165 Hz vrefresh with a dot clock of 635.540 Mhz.
+
+Refine calculations to avoid the overflows.
+
+Tested for DCE-10 with R9 380 Tonga + ASUS ROG PG279 panel.
+
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/dce_v10_0.c |   19 +++----------------
+ drivers/gpu/drm/amd/amdgpu/dce_v11_0.c |   19 +++----------------
+ drivers/gpu/drm/amd/amdgpu/dce_v6_0.c  |   19 +++----------------
+ drivers/gpu/drm/amd/amdgpu/dce_v8_0.c  |   19 +++----------------
+ 4 files changed, 12 insertions(+), 64 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+@@ -1090,23 +1090,10 @@ static u32 dce_v10_0_latency_watermark(s
+       a.full = dfixed_const(available_bandwidth);
+       b.full = dfixed_const(wm->num_heads);
+       a.full = dfixed_div(a, b);
++      tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
++      tmp = min(dfixed_trunc(a), tmp);
+-      b.full = dfixed_const(mc_latency + 512);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(b, c);
+-
+-      c.full = dfixed_const(dmif_size);
+-      b.full = dfixed_div(c, b);
+-
+-      tmp = min(dfixed_trunc(a), dfixed_trunc(b));
+-
+-      b.full = dfixed_const(1000);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(c, b);
+-      c.full = dfixed_const(wm->bytes_per_pixel);
+-      b.full = dfixed_mul(b, c);
+-
+-      lb_fill_bw = min(tmp, dfixed_trunc(b));
++      lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
+       a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
+       b.full = dfixed_const(1000);
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+@@ -1059,23 +1059,10 @@ static u32 dce_v11_0_latency_watermark(s
+       a.full = dfixed_const(available_bandwidth);
+       b.full = dfixed_const(wm->num_heads);
+       a.full = dfixed_div(a, b);
++      tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
++      tmp = min(dfixed_trunc(a), tmp);
+-      b.full = dfixed_const(mc_latency + 512);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(b, c);
+-
+-      c.full = dfixed_const(dmif_size);
+-      b.full = dfixed_div(c, b);
+-
+-      tmp = min(dfixed_trunc(a), dfixed_trunc(b));
+-
+-      b.full = dfixed_const(1000);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(c, b);
+-      c.full = dfixed_const(wm->bytes_per_pixel);
+-      b.full = dfixed_mul(b, c);
+-
+-      lb_fill_bw = min(tmp, dfixed_trunc(b));
++      lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
+       a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
+       b.full = dfixed_const(1000);
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+@@ -861,23 +861,10 @@ static u32 dce_v6_0_latency_watermark(st
+       a.full = dfixed_const(available_bandwidth);
+       b.full = dfixed_const(wm->num_heads);
+       a.full = dfixed_div(a, b);
++      tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
++      tmp = min(dfixed_trunc(a), tmp);
+-      b.full = dfixed_const(mc_latency + 512);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(b, c);
+-
+-      c.full = dfixed_const(dmif_size);
+-      b.full = dfixed_div(c, b);
+-
+-      tmp = min(dfixed_trunc(a), dfixed_trunc(b));
+-
+-      b.full = dfixed_const(1000);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(c, b);
+-      c.full = dfixed_const(wm->bytes_per_pixel);
+-      b.full = dfixed_mul(b, c);
+-
+-      lb_fill_bw = min(tmp, dfixed_trunc(b));
++      lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
+       a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
+       b.full = dfixed_const(1000);
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+@@ -974,23 +974,10 @@ static u32 dce_v8_0_latency_watermark(st
+       a.full = dfixed_const(available_bandwidth);
+       b.full = dfixed_const(wm->num_heads);
+       a.full = dfixed_div(a, b);
++      tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
++      tmp = min(dfixed_trunc(a), tmp);
+-      b.full = dfixed_const(mc_latency + 512);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(b, c);
+-
+-      c.full = dfixed_const(dmif_size);
+-      b.full = dfixed_div(c, b);
+-
+-      tmp = min(dfixed_trunc(a), dfixed_trunc(b));
+-
+-      b.full = dfixed_const(1000);
+-      c.full = dfixed_const(wm->disp_clk);
+-      b.full = dfixed_div(c, b);
+-      c.full = dfixed_const(wm->bytes_per_pixel);
+-      b.full = dfixed_mul(b, c);
+-
+-      lb_fill_bw = min(tmp, dfixed_trunc(b));
++      lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
+       a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
+       b.full = dfixed_const(1000);
diff --git a/queue-4.11/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch b/queue-4.11/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch
new file mode 100644 (file)
index 0000000..7e9383c
--- /dev/null
@@ -0,0 +1,182 @@
+From d63c277dc672e0c568481af043359420fa9d4736 Mon Sep 17 00:00:00 2001
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+Date: Wed, 29 Mar 2017 22:09:11 +0200
+Subject: drm/amdgpu: Make display watermark calculations more accurate
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+commit d63c277dc672e0c568481af043359420fa9d4736 upstream.
+
+Avoid big roundoff errors in scanline/hactive durations for
+high pixel clocks, especially for >= 500 Mhz, and thereby
+program more accurate display fifo watermarks.
+
+Implemented here for DCE 6,8,10,11.
+Successfully tested on DCE 10 with AMD R9 380 Tonga.
+
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/dce_v10_0.c |   10 +++++-----
+ drivers/gpu/drm/amd/amdgpu/dce_v11_0.c |   10 +++++-----
+ drivers/gpu/drm/amd/amdgpu/dce_v6_0.c  |   10 +++++-----
+ drivers/gpu/drm/amd/amdgpu/dce_v8_0.c  |   10 +++++-----
+ 4 files changed, 20 insertions(+), 20 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+@@ -1214,14 +1214,14 @@ static void dce_v10_0_program_watermarks
+ {
+       struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
+       struct dce10_wm_params wm_low, wm_high;
+-      u32 pixel_period;
++      u32 active_time;
+       u32 line_time = 0;
+       u32 latency_watermark_a = 0, latency_watermark_b = 0;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
+       if (amdgpu_crtc->base.enabled && num_heads && mode) {
+-              pixel_period = 1000000 / (u32)mode->clock;
+-              line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
++              active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
++              line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               /* watermark for high clocks */
+               if (adev->pm.dpm_enabled) {
+@@ -1236,7 +1236,7 @@ static void dce_v10_0_program_watermarks
+               wm_high.disp_clk = mode->clock;
+               wm_high.src_width = mode->crtc_hdisplay;
+-              wm_high.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_high.active_time = active_time;
+               wm_high.blank_time = line_time - wm_high.active_time;
+               wm_high.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+@@ -1275,7 +1275,7 @@ static void dce_v10_0_program_watermarks
+               wm_low.disp_clk = mode->clock;
+               wm_low.src_width = mode->crtc_hdisplay;
+-              wm_low.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_low.active_time = active_time;
+               wm_low.blank_time = line_time - wm_low.active_time;
+               wm_low.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+@@ -1183,14 +1183,14 @@ static void dce_v11_0_program_watermarks
+ {
+       struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
+       struct dce10_wm_params wm_low, wm_high;
+-      u32 pixel_period;
++      u32 active_time;
+       u32 line_time = 0;
+       u32 latency_watermark_a = 0, latency_watermark_b = 0;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
+       if (amdgpu_crtc->base.enabled && num_heads && mode) {
+-              pixel_period = 1000000 / (u32)mode->clock;
+-              line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
++              active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
++              line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               /* watermark for high clocks */
+               if (adev->pm.dpm_enabled) {
+@@ -1205,7 +1205,7 @@ static void dce_v11_0_program_watermarks
+               wm_high.disp_clk = mode->clock;
+               wm_high.src_width = mode->crtc_hdisplay;
+-              wm_high.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_high.active_time = active_time;
+               wm_high.blank_time = line_time - wm_high.active_time;
+               wm_high.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+@@ -1244,7 +1244,7 @@ static void dce_v11_0_program_watermarks
+               wm_low.disp_clk = mode->clock;
+               wm_low.src_width = mode->crtc_hdisplay;
+-              wm_low.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_low.active_time = active_time;
+               wm_low.blank_time = line_time - wm_low.active_time;
+               wm_low.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+@@ -986,7 +986,7 @@ static void dce_v6_0_program_watermarks(
+       struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
+       struct dce6_wm_params wm_low, wm_high;
+       u32 dram_channels;
+-      u32 pixel_period;
++      u32 active_time;
+       u32 line_time = 0;
+       u32 latency_watermark_a = 0, latency_watermark_b = 0;
+       u32 priority_a_mark = 0, priority_b_mark = 0;
+@@ -996,8 +996,8 @@ static void dce_v6_0_program_watermarks(
+       fixed20_12 a, b, c;
+       if (amdgpu_crtc->base.enabled && num_heads && mode) {
+-              pixel_period = 1000000 / (u32)mode->clock;
+-              line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
++              active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
++              line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               priority_a_cnt = 0;
+               priority_b_cnt = 0;
+@@ -1016,7 +1016,7 @@ static void dce_v6_0_program_watermarks(
+               wm_high.disp_clk = mode->clock;
+               wm_high.src_width = mode->crtc_hdisplay;
+-              wm_high.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_high.active_time = active_time;
+               wm_high.blank_time = line_time - wm_high.active_time;
+               wm_high.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+@@ -1043,7 +1043,7 @@ static void dce_v6_0_program_watermarks(
+               wm_low.disp_clk = mode->clock;
+               wm_low.src_width = mode->crtc_hdisplay;
+-              wm_low.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_low.active_time = active_time;
+               wm_low.blank_time = line_time - wm_low.active_time;
+               wm_low.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+@@ -1098,14 +1098,14 @@ static void dce_v8_0_program_watermarks(
+ {
+       struct drm_display_mode *mode = &amdgpu_crtc->base.mode;
+       struct dce8_wm_params wm_low, wm_high;
+-      u32 pixel_period;
++      u32 active_time;
+       u32 line_time = 0;
+       u32 latency_watermark_a = 0, latency_watermark_b = 0;
+       u32 tmp, wm_mask, lb_vblank_lead_lines = 0;
+       if (amdgpu_crtc->base.enabled && num_heads && mode) {
+-              pixel_period = 1000000 / (u32)mode->clock;
+-              line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
++              active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
++              line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+               /* watermark for high clocks */
+               if (adev->pm.dpm_enabled) {
+@@ -1120,7 +1120,7 @@ static void dce_v8_0_program_watermarks(
+               wm_high.disp_clk = mode->clock;
+               wm_high.src_width = mode->crtc_hdisplay;
+-              wm_high.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_high.active_time = active_time;
+               wm_high.blank_time = line_time - wm_high.active_time;
+               wm_high.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+@@ -1159,7 +1159,7 @@ static void dce_v8_0_program_watermarks(
+               wm_low.disp_clk = mode->clock;
+               wm_low.src_width = mode->crtc_hdisplay;
+-              wm_low.active_time = mode->crtc_hdisplay * pixel_period;
++              wm_low.active_time = active_time;
+               wm_low.blank_time = line_time - wm_low.active_time;
+               wm_low.interlaced = false;
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
diff --git a/queue-4.11/drm-nouveau-kms-nv50-fix-source-rect-only-plane-updates.patch b/queue-4.11/drm-nouveau-kms-nv50-fix-source-rect-only-plane-updates.patch
new file mode 100644 (file)
index 0000000..805b00f
--- /dev/null
@@ -0,0 +1,39 @@
+From 36601c2b36e27435d9be33cfa092120ff69914eb Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon, 1 May 2017 16:52:03 +1000
+Subject: drm/nouveau/kms/nv50: fix source-rect-only plane updates
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 36601c2b36e27435d9be33cfa092120ff69914eb upstream.
+
+This "optimisation" (which was originally meant to skip updating cursor
+settings in the core channel on position-only updates) turned out to be
+pointless in the final design of the code before it was merged.
+
+Remove it completely, as it breaks other cases.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nv50_display.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nv50_display.c
++++ b/drivers/gpu/drm/nouveau/nv50_display.c
+@@ -906,11 +906,9 @@ nv50_wndw_atomic_check(struct drm_plane
+               if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point)))
+                       asyw->set.point = true;
+-              if (!varm || asym || armw->state.fb != asyw->state.fb) {
+-                      ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh);
+-                      if (ret)
+-                              return ret;
+-              }
++              ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh);
++              if (ret)
++                      return ret;
+       } else
+       if (varm) {
+               nv50_wndw_atomic_check_release(wndw, asyw, harm);
diff --git a/queue-4.11/drm-nouveau-kms-nv50-skip-core-channel-cursor-update-on-position-only-changes.patch b/queue-4.11/drm-nouveau-kms-nv50-skip-core-channel-cursor-update-on-position-only-changes.patch
new file mode 100644 (file)
index 0000000..0924ee1
--- /dev/null
@@ -0,0 +1,40 @@
+From e6db95799b1b870aae15682a6d0898df9e9dfb38 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Mon, 1 May 2017 16:53:40 +1000
+Subject: drm/nouveau/kms/nv50: skip core channel cursor update on position-only changes
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit e6db95799b1b870aae15682a6d0898df9e9dfb38 upstream.
+
+The DRM core used to only call prepare_fb/cleanup_fb() when a plane's
+framebuffer changed, which achieved the desired effect.
+
+It's apparently now up to the driver to decide on its own.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nv50_display.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nv50_display.c
++++ b/drivers/gpu/drm/nouveau/nv50_display.c
+@@ -1113,9 +1113,13 @@ static void
+ nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
+                 struct nv50_wndw_atom *asyw)
+ {
+-      asyh->curs.handle = nv50_disp(wndw->plane.dev)->mast.base.vram.handle;
+-      asyh->curs.offset = asyw->image.offset;
+-      asyh->set.curs = asyh->curs.visible;
++      u32 handle = nv50_disp(wndw->plane.dev)->mast.base.vram.handle;
++      u32 offset = asyw->image.offset;
++      if (asyh->curs.handle != handle || asyh->curs.offset != offset) {
++              asyh->curs.handle = handle;
++              asyh->curs.offset = offset;
++              asyh->set.curs = asyh->curs.visible;
++      }
+ }
+ static void
diff --git a/queue-4.11/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch b/queue-4.11/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch
new file mode 100644 (file)
index 0000000..50f3534
--- /dev/null
@@ -0,0 +1,40 @@
+From ac799acaa4d8db4f7dcd968b15c9596c80a4677f Mon Sep 17 00:00:00 2001
+From: Ilia Mirkin <imirkin@alum.mit.edu>
+Date: Sat, 18 Mar 2017 16:23:10 -0400
+Subject: drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one
+
+From: Ilia Mirkin <imirkin@alum.mit.edu>
+
+commit ac799acaa4d8db4f7dcd968b15c9596c80a4677f upstream.
+
+The NV4A (aka NV44A) is an oddity in the family. It only comes in AGP
+and PCI varieties, rather than a core PCIE chip with a bridge for
+AGP/PCI as necessary. As a result, it appears that the MMU is also
+non-functional. For AGP cards, the vast majority of the NV4A lineup,
+this worked out since we force AGP cards to use the nv04 mmu. However
+for PCI variants, this did not work.
+
+Switching to the NV04 MMU makes it work like a charm. Thanks to mwk for
+the suggestion. This should be a no-op for NV4A AGP boards, as they were
+using it already.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388
+Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/device/base.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+@@ -584,7 +584,7 @@ nv44_chipset = {
+       .i2c = nv04_i2c_new,
+       .imem = nv40_instmem_new,
+       .mc = nv44_mc_new,
+-      .mmu = nv44_mmu_new,
++      .mmu = nv04_mmu_new,
+       .pci = nv40_pci_new,
+       .therm = nv40_therm_new,
+       .timer = nv41_timer_new,
diff --git a/queue-4.11/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch b/queue-4.11/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch
new file mode 100644 (file)
index 0000000..817a9ea
--- /dev/null
@@ -0,0 +1,66 @@
+From e4311ee51d1e2676001b2d8fcefd92bdd79aad85 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 11 May 2017 17:33:39 +1000
+Subject: drm/nouveau/therm: remove ineffective workarounds for alarm bugs
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit e4311ee51d1e2676001b2d8fcefd92bdd79aad85 upstream.
+
+These were ineffective due to touching the list without the alarm lock,
+but should no longer be required.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c   |    2 +-
+ drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c    |    2 +-
+ drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c |    2 +-
+ drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c   |    2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
+@@ -146,7 +146,7 @@ nvkm_therm_update(struct nvkm_therm *the
+               poll = false;
+       }
+-      if (list_empty(&therm->alarm.head) && poll)
++      if (poll)
+               nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm);
+       spin_unlock_irqrestore(&therm->lock, flags);
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c
+@@ -83,7 +83,7 @@ nvkm_fan_update(struct nvkm_fan *fan, bo
+       spin_unlock_irqrestore(&fan->lock, flags);
+       /* schedule next fan update, if not at target speed already */
+-      if (list_empty(&fan->alarm.head) && target != duty) {
++      if (target != duty) {
+               u16 bump_period = fan->bios.bump_period;
+               u16 slow_down_period = fan->bios.slow_down_period;
+               u64 delay;
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c
+@@ -53,7 +53,7 @@ nvkm_fantog_update(struct nvkm_fantog *f
+       duty = !nvkm_gpio_get(gpio, 0, DCB_GPIO_FAN, 0xff);
+       nvkm_gpio_set(gpio, 0, DCB_GPIO_FAN, 0xff, duty);
+-      if (list_empty(&fan->alarm.head) && percent != (duty * 100)) {
++      if (percent != (duty * 100)) {
+               u64 next_change = (percent * fan->period_us) / 100;
+               if (!duty)
+                       next_change = fan->period_us - next_change;
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
+@@ -185,7 +185,7 @@ alarm_timer_callback(struct nvkm_alarm *
+       spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags);
+       /* schedule the next poll in one second */
+-      if (therm->func->temp_get(therm) >= 0 && list_empty(&alarm->head))
++      if (therm->func->temp_get(therm) >= 0)
+               nvkm_timer_alarm(tmr, 1000000000ULL, alarm);
+ }
diff --git a/queue-4.11/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch b/queue-4.11/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch
new file mode 100644 (file)
index 0000000..9de8848
--- /dev/null
@@ -0,0 +1,31 @@
+From 3733bd8b407211739e72d051e5f30ad82a52c4bc Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 11 May 2017 16:53:42 +1000
+Subject: drm/nouveau/tmr: ack interrupt before processing alarms
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 3733bd8b407211739e72d051e5f30ad82a52c4bc upstream.
+
+Fixes a race where we can miss an alarm that triggers while we're already
+processing previous alarms.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c
+@@ -76,8 +76,8 @@ nv04_timer_intr(struct nvkm_timer *tmr)
+       u32 stat = nvkm_rd32(device, NV04_PTIMER_INTR_0);
+       if (stat & 0x00000001) {
+-              nvkm_timer_alarm_trigger(tmr);
+               nvkm_wr32(device, NV04_PTIMER_INTR_0, 0x00000001);
++              nvkm_timer_alarm_trigger(tmr);
+               stat &= ~0x00000001;
+       }
diff --git a/queue-4.11/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch b/queue-4.11/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch
new file mode 100644 (file)
index 0000000..ba5c6e0
--- /dev/null
@@ -0,0 +1,50 @@
+From 330bdf62fe6a6c5b99a647f7bf7157107c9348b3 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 11 May 2017 17:13:29 +1000
+Subject: drm/nouveau/tmr: avoid processing completed alarms when adding a new one
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 330bdf62fe6a6c5b99a647f7bf7157107c9348b3 upstream.
+
+The idea here was to avoid having to "manually" program the HW if there's
+a new earliest alarm.  This was lazy and bad, as it leads to loads of fun
+races between inter-related callers (ie. therm).
+
+Turns out, it's not so difficult after all.  Go figure ;)
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
+@@ -80,12 +80,22 @@ nvkm_timer_alarm(struct nvkm_timer *tmr,
+                       if (list->timestamp > alarm->timestamp)
+                               break;
+               }
++
+               list_add_tail(&alarm->head, &list->head);
++
++              /* Update HW if this is now the earliest alarm. */
++              list = list_first_entry(&tmr->alarms, typeof(*list), head);
++              if (list == alarm) {
++                      tmr->func->alarm_init(tmr, alarm->timestamp);
++                      /* This shouldn't happen if callers aren't stupid.
++                       *
++                       * Worst case scenario is that it'll take roughly
++                       * 4 seconds for the next alarm to trigger.
++                       */
++                      WARN_ON(alarm->timestamp <= nvkm_timer_read(tmr));
++              }
+       }
+       spin_unlock_irqrestore(&tmr->lock, flags);
+-
+-      /* process pending alarms */
+-      nvkm_timer_alarm_trigger(tmr);
+ }
+ void
diff --git a/queue-4.11/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch b/queue-4.11/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch
new file mode 100644 (file)
index 0000000..462e7ca
--- /dev/null
@@ -0,0 +1,49 @@
+From 9fc64667ee48c9a25e7dca1a6bcb6906fec5bcc5 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 11 May 2017 17:03:05 +1000
+Subject: drm/nouveau/tmr: fix corruption of the pending list when rescheduling an alarm
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 9fc64667ee48c9a25e7dca1a6bcb6906fec5bcc5 upstream.
+
+At least therm/fantog "attempts" to work around this issue, which could
+lead to corruption of the pending alarm list.
+
+Fix it properly by not updating the timestamp without the lock held, or
+trying to add an already pending alarm to the pending alarm list....
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c |   17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
+@@ -65,14 +65,17 @@ nvkm_timer_alarm(struct nvkm_timer *tmr,
+       struct nvkm_alarm *list;
+       unsigned long flags;
+-      alarm->timestamp = nvkm_timer_read(tmr) + nsec;
+-
+-      /* append new alarm to list, in soonest-alarm-first order */
++      /* Remove alarm from pending list.
++       *
++       * This both protects against the corruption of the list,
++       * and implements alarm rescheduling/cancellation.
++       */
+       spin_lock_irqsave(&tmr->lock, flags);
+-      if (!nsec) {
+-              if (!list_empty(&alarm->head))
+-                      list_del(&alarm->head);
+-      } else {
++      list_del_init(&alarm->head);
++
++      if (nsec) {
++              /* Insert into pending list, ordered earliest to latest. */
++              alarm->timestamp = nvkm_timer_read(tmr) + nsec;
+               list_for_each_entry(list, &tmr->alarms, head) {
+                       if (list->timestamp > alarm->timestamp)
+                               break;
diff --git a/queue-4.11/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch b/queue-4.11/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch
new file mode 100644 (file)
index 0000000..8141f97
--- /dev/null
@@ -0,0 +1,63 @@
+From 1b0f84380b10ee97f7d2dd191294de9017e94d1d Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Thu, 11 May 2017 17:19:48 +1000
+Subject: drm/nouveau/tmr: handle races with hw when updating the next alarm time
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 1b0f84380b10ee97f7d2dd191294de9017e94d1d upstream.
+
+If the time to the next alarm is short enough, we could race with HW and
+end up with an ~4 second delay until it triggers.
+
+Fix this by checking again after we update HW.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c |   26 ++++++++++++++---------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
+@@ -36,23 +36,29 @@ nvkm_timer_alarm_trigger(struct nvkm_tim
+       unsigned long flags;
+       LIST_HEAD(exec);
+-      /* move any due alarms off the pending list */
++      /* Process pending alarms. */
+       spin_lock_irqsave(&tmr->lock, flags);
+       list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) {
+-              if (alarm->timestamp <= nvkm_timer_read(tmr))
+-                      list_move_tail(&alarm->head, &exec);
++              /* Have we hit the earliest alarm that hasn't gone off? */
++              if (alarm->timestamp > nvkm_timer_read(tmr)) {
++                      /* Schedule it.  If we didn't race, we're done. */
++                      tmr->func->alarm_init(tmr, alarm->timestamp);
++                      if (alarm->timestamp > nvkm_timer_read(tmr))
++                              break;
++              }
++
++              /* Move to completed list.  We'll drop the lock before
++               * executing the callback so it can reschedule itself.
++               */
++              list_move_tail(&alarm->head, &exec);
+       }
+-      /* reschedule interrupt for next alarm time */
+-      if (!list_empty(&tmr->alarms)) {
+-              alarm = list_first_entry(&tmr->alarms, typeof(*alarm), head);
+-              tmr->func->alarm_init(tmr, alarm->timestamp);
+-      } else {
++      /* Shut down interrupt if no more pending alarms. */
++      if (list_empty(&tmr->alarms))
+               tmr->func->alarm_fini(tmr);
+-      }
+       spin_unlock_irqrestore(&tmr->lock, flags);
+-      /* execute any pending alarm handlers */
++      /* Execute completed callbacks. */
+       list_for_each_entry_safe(alarm, atemp, &exec, head) {
+               list_del_init(&alarm->head);
+               alarm->func(alarm);
diff --git a/queue-4.11/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch b/queue-4.11/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch
new file mode 100644 (file)
index 0000000..0e4615b
--- /dev/null
@@ -0,0 +1,94 @@
+From 83977443938122baeed28dc9f078db3da9855f7c Mon Sep 17 00:00:00 2001
+From: David Rivshin <DRivshin@allworx.com>
+Date: Mon, 24 Apr 2017 18:56:50 -0400
+Subject: gpio: omap: return error if requested debounce time is not possible
+
+From: David Rivshin <DRivshin@allworx.com>
+
+commit 83977443938122baeed28dc9f078db3da9855f7c upstream.
+
+omap_gpio_debounce() does not validate that the requested debounce
+is within a range it can handle. Instead it lets the register value
+wrap silently, and always returns success.
+
+This can lead to all sorts of unexpected behavior, such as gpio_keys
+asking for a too-long debounce, but getting a very short debounce in
+practice.
+
+Fix this by returning -EINVAL if the requested value does not fit into
+the register field. If there is no debounce clock available at all,
+return -ENOTSUPP.
+
+Fixes: e85ec6c3047b ("gpio: omap: fix omap2_set_gpio_debounce")
+Signed-off-by: David Rivshin <drivshin@allworx.com>
+Acked-by: Grygorii Strashko <grygorii.strashko@ti.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-omap.c |   23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpio/gpio-omap.c
++++ b/drivers/gpio/gpio-omap.c
+@@ -208,9 +208,11 @@ static inline void omap_gpio_dbck_disabl
+  * OMAP's debounce time is in 31us steps
+  *   <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
+  * so we need to convert and round up to the closest unit.
++ *
++ * Return: 0 on success, negative error otherwise.
+  */
+-static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
+-                                  unsigned debounce)
++static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
++                                 unsigned debounce)
+ {
+       void __iomem            *reg;
+       u32                     val;
+@@ -218,11 +220,12 @@ static void omap2_set_gpio_debounce(stru
+       bool                    enable = !!debounce;
+       if (!bank->dbck_flag)
+-              return;
++              return -ENOTSUPP;
+       if (enable) {
+               debounce = DIV_ROUND_UP(debounce, 31) - 1;
+-              debounce &= OMAP4_GPIO_DEBOUNCINGTIME_MASK;
++              if ((debounce & OMAP4_GPIO_DEBOUNCINGTIME_MASK) != debounce)
++                      return -EINVAL;
+       }
+       l = BIT(offset);
+@@ -255,6 +258,8 @@ static void omap2_set_gpio_debounce(stru
+               bank->context.debounce = debounce;
+               bank->context.debounce_en = val;
+       }
++
++      return 0;
+ }
+ /**
+@@ -964,14 +969,20 @@ static int omap_gpio_debounce(struct gpi
+ {
+       struct gpio_bank *bank;
+       unsigned long flags;
++      int ret;
+       bank = gpiochip_get_data(chip);
+       raw_spin_lock_irqsave(&bank->lock, flags);
+-      omap2_set_gpio_debounce(bank, offset, debounce);
++      ret = omap2_set_gpio_debounce(bank, offset, debounce);
+       raw_spin_unlock_irqrestore(&bank->lock, flags);
+-      return 0;
++      if (ret)
++              dev_info(chip->parent,
++                       "Could not set line %u debounce to %u microseconds (%d)",
++                       offset, debounce, ret);
++
++      return ret;
+ }
+ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset,
diff --git a/queue-4.11/ibmvscsis-do-not-send-aborted-task-response.patch b/queue-4.11/ibmvscsis-do-not-send-aborted-task-response.patch
new file mode 100644 (file)
index 0000000..8316e28
--- /dev/null
@@ -0,0 +1,242 @@
+From 25e78531268e9240fc594ce76587601b873d37c9 Mon Sep 17 00:00:00 2001
+From: "Bryant G. Ly" <bryantly@linux.vnet.ibm.com>
+Date: Fri, 5 May 2017 14:17:15 -0500
+Subject: ibmvscsis: Do not send aborted task response
+
+From: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
+
+commit 25e78531268e9240fc594ce76587601b873d37c9 upstream.
+
+The driver is sending a response to the actual scsi op that was
+aborted by an abort task TM, while LIO is sending a response to
+the abort task TM.
+
+ibmvscsis_tgt does not send the response to the client until
+release_cmd time. The reason for this was because if we did it
+at queue_status time, then the client would be free to reuse the
+tag for that command, but we're still using the tag until the
+command is released at release_cmd time, so we chose to delay
+sending the response until then. That then caused this issue, because
+release_cmd is always called, even if queue_status is not.
+
+SCSI spec says that the initiator that sends the abort task
+TM NEVER gets a response to the aborted op and with the current
+code it will send a response. Thus this fix will remove that response
+if the CMD_T_ABORTED && !CMD_T_TAS.
+
+Another case with a small timing window is the case where if LIO sends a
+TMR_DOES_NOT_EXIST, and the release_cmd callback is called for the TMR Abort
+cmd before the release_cmd for the (attemped) aborted cmd, then we need to
+ensure that we send the response for the (attempted) abort cmd to the client
+before we send the response for the TMR Abort cmd.
+
+Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
+Signed-off-by: Michael Cyr <mikecyr@linux.vnet.ibm.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  120 +++++++++++++++++++++++--------
+ drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h |    2 
+ 2 files changed, 94 insertions(+), 28 deletions(-)
+
+--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
++++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+@@ -1170,6 +1170,7 @@ static struct ibmvscsis_cmd *ibmvscsis_g
+               cmd = list_first_entry_or_null(&vscsi->free_cmd,
+                                              struct ibmvscsis_cmd, list);
+               if (cmd) {
++                      cmd->flags &= ~(DELAY_SEND);
+                       list_del(&cmd->list);
+                       cmd->iue = iue;
+                       cmd->type = UNSET_TYPE;
+@@ -1749,45 +1750,79 @@ static void srp_snd_msg_failed(struct sc
+ static void ibmvscsis_send_messages(struct scsi_info *vscsi)
+ {
+       u64 msg_hi = 0;
+-      /* note do not attmempt to access the IU_data_ptr with this pointer
++      /* note do not attempt to access the IU_data_ptr with this pointer
+        * it is not valid
+        */
+       struct viosrp_crq *crq = (struct viosrp_crq *)&msg_hi;
+       struct ibmvscsis_cmd *cmd, *nxt;
+       struct iu_entry *iue;
+       long rc = ADAPT_SUCCESS;
++      bool retry = false;
+       if (!(vscsi->flags & RESPONSE_Q_DOWN)) {
+-              list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp, list) {
+-                      iue = cmd->iue;
+-
+-                      crq->valid = VALID_CMD_RESP_EL;
+-                      crq->format = cmd->rsp.format;
+-
+-                      if (cmd->flags & CMD_FAST_FAIL)
+-                              crq->status = VIOSRP_ADAPTER_FAIL;
+-
+-                      crq->IU_length = cpu_to_be16(cmd->rsp.len);
++              do {
++                      retry = false;
++                      list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp,
++                                               list) {
++                              /*
++                               * Check to make sure abort cmd gets processed
++                               * prior to the abort tmr cmd
++                               */
++                              if (cmd->flags & DELAY_SEND)
++                                      continue;
+-                      rc = h_send_crq(vscsi->dma_dev->unit_address,
+-                                      be64_to_cpu(msg_hi),
+-                                      be64_to_cpu(cmd->rsp.tag));
++                              if (cmd->abort_cmd) {
++                                      retry = true;
++                                      cmd->abort_cmd->flags &= ~(DELAY_SEND);
++                              }
+-                      pr_debug("send_messages: cmd %p, tag 0x%llx, rc %ld\n",
+-                               cmd, be64_to_cpu(cmd->rsp.tag), rc);
++                              /*
++                               * If CMD_T_ABORTED w/o CMD_T_TAS scenarios and
++                               * the case where LIO issued a
++                               * ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST
++                               * case then we dont send a response, since it
++                               * was already done.
++                               */
++                              if (cmd->se_cmd.transport_state & CMD_T_ABORTED &&
++                                  !(cmd->se_cmd.transport_state & CMD_T_TAS)) {
++                                      list_del(&cmd->list);
++                                      ibmvscsis_free_cmd_resources(vscsi,
++                                                                   cmd);
++                              } else {
++                                      iue = cmd->iue;
++
++                                      crq->valid = VALID_CMD_RESP_EL;
++                                      crq->format = cmd->rsp.format;
++
++                                      if (cmd->flags & CMD_FAST_FAIL)
++                                              crq->status = VIOSRP_ADAPTER_FAIL;
++
++                                      crq->IU_length = cpu_to_be16(cmd->rsp.len);
++
++                                      rc = h_send_crq(vscsi->dma_dev->unit_address,
++                                                      be64_to_cpu(msg_hi),
++                                                      be64_to_cpu(cmd->rsp.tag));
+-                      /* if all ok free up the command element resources */
+-                      if (rc == H_SUCCESS) {
+-                              /* some movement has occurred */
+-                              vscsi->rsp_q_timer.timer_pops = 0;
+-                              list_del(&cmd->list);
++                                      pr_debug("send_messages: cmd %p, tag 0x%llx, rc %ld\n",
++                                               cmd, be64_to_cpu(cmd->rsp.tag), rc);
+-                              ibmvscsis_free_cmd_resources(vscsi, cmd);
+-                      } else {
+-                              srp_snd_msg_failed(vscsi, rc);
+-                              break;
++                                      /* if all ok free up the command
++                                       * element resources
++                                       */
++                                      if (rc == H_SUCCESS) {
++                                              /* some movement has occurred */
++                                              vscsi->rsp_q_timer.timer_pops = 0;
++                                              list_del(&cmd->list);
++
++                                              ibmvscsis_free_cmd_resources(vscsi,
++                                                                           cmd);
++                                      } else {
++                                              srp_snd_msg_failed(vscsi, rc);
++                                              break;
++                                      }
++                              }
+                       }
+-              }
++              } while (retry);
+               if (!rc) {
+                       /*
+@@ -2708,6 +2743,7 @@ static int ibmvscsis_alloc_cmds(struct s
+       for (i = 0, cmd = (struct ibmvscsis_cmd *)vscsi->cmd_pool; i < num;
+            i++, cmd++) {
++              cmd->abort_cmd = NULL;
+               cmd->adapter = vscsi;
+               INIT_WORK(&cmd->work, ibmvscsis_scheduler);
+               list_add_tail(&cmd->list, &vscsi->free_cmd);
+@@ -3579,9 +3615,20 @@ static int ibmvscsis_write_pending(struc
+ {
+       struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+                                                se_cmd);
++      struct scsi_info *vscsi = cmd->adapter;
+       struct iu_entry *iue = cmd->iue;
+       int rc;
++      /*
++       * If CLIENT_FAILED OR RESPONSE_Q_DOWN, then just return success
++       * since LIO can't do anything about it, and we dont want to
++       * attempt an srp_transfer_data.
++       */
++      if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) {
++              pr_err("write_pending failed since: %d\n", vscsi->flags);
++              return 0;
++      }
++
+       rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma,
+                              1, 1);
+       if (rc) {
+@@ -3660,11 +3707,28 @@ static void ibmvscsis_queue_tm_rsp(struc
+       struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
+                                                se_cmd);
+       struct scsi_info *vscsi = cmd->adapter;
++      struct ibmvscsis_cmd *cmd_itr;
++      struct iu_entry *iue = iue = cmd->iue;
++      struct srp_tsk_mgmt *srp_tsk = &vio_iu(iue)->srp.tsk_mgmt;
++      u64 tag_to_abort = be64_to_cpu(srp_tsk->task_tag);
+       uint len;
+       pr_debug("queue_tm_rsp %p, status %d\n",
+                se_cmd, (int)se_cmd->se_tmr_req->response);
++      if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK &&
++          cmd->se_cmd.se_tmr_req->response == TMR_TASK_DOES_NOT_EXIST) {
++              spin_lock_bh(&vscsi->intr_lock);
++              list_for_each_entry(cmd_itr, &vscsi->active_q, list) {
++                      if (tag_to_abort == cmd_itr->se_cmd.tag) {
++                              cmd_itr->abort_cmd = cmd;
++                              cmd->flags |= DELAY_SEND;
++                              break;
++                      }
++              }
++              spin_unlock_bh(&vscsi->intr_lock);
++      }
++
+       srp_build_response(vscsi, cmd, &len);
+       cmd->rsp.format = SRP_FORMAT;
+       cmd->rsp.len = len;
+@@ -3672,8 +3736,8 @@ static void ibmvscsis_queue_tm_rsp(struc
+ static void ibmvscsis_aborted_task(struct se_cmd *se_cmd)
+ {
+-      /* TBD: What (if anything) should we do here? */
+-      pr_debug("ibmvscsis_aborted_task %p\n", se_cmd);
++      pr_debug("ibmvscsis_aborted_task %p task_tag: %llu\n",
++               se_cmd, se_cmd->tag);
+ }
+ static struct se_wwn *ibmvscsis_make_tport(struct target_fabric_configfs *tf,
+--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
++++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.h
+@@ -168,10 +168,12 @@ struct ibmvscsis_cmd {
+       struct iu_rsp rsp;
+       struct work_struct work;
+       struct scsi_info *adapter;
++      struct ibmvscsis_cmd *abort_cmd;
+       /* Sense buffer that will be mapped into outgoing status */
+       unsigned char sense_buf[TRANSPORT_SENSE_BUFFER];
+       u64 init_time;
+ #define CMD_FAST_FAIL BIT(0)
++#define DELAY_SEND    BIT(1)
+       u32 flags;
+       char type;
+ };
diff --git a/queue-4.11/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch b/queue-4.11/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch
new file mode 100644 (file)
index 0000000..afc69d1
--- /dev/null
@@ -0,0 +1,44 @@
+From ed3730c435f1a9f9559ed7762035d22d8a95adfe Mon Sep 17 00:00:00 2001
+From: Andreas Klinger <ak@it-klinger.de>
+Date: Mon, 10 Apr 2017 19:00:01 +0200
+Subject: IIO: bmp280-core.c: fix error in humidity calculation
+
+From: Andreas Klinger <ak@it-klinger.de>
+
+commit ed3730c435f1a9f9559ed7762035d22d8a95adfe upstream.
+
+While calculating the compensation of the humidity there are negative values
+interpreted as unsigned because of unsigned variables used.  These values as
+well as the constants need to be casted to signed as indicated by the
+documentation of the sensor.
+
+Signed-off-by: Andreas Klinger <ak@it-klinger.de>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Matt Ranostay <matt.ranostay@konsulko.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/pressure/bmp280-core.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/iio/pressure/bmp280-core.c
++++ b/drivers/iio/pressure/bmp280-core.c
+@@ -175,11 +175,12 @@ static u32 bmp280_compensate_humidity(st
+       }
+       H6 = sign_extend32(tmp, 7);
+-      var = ((s32)data->t_fine) - 76800;
+-      var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + 16384) >> 15)
+-              * (((((((var * H6) >> 10) * (((var * H3) >> 11) + 32768)) >> 10)
+-              + 2097152) * H2 + 8192) >> 14);
+-      var -= ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
++      var = ((s32)data->t_fine) - (s32)76800;
++      var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var))
++              + (s32)16384) >> 15) * (((((((var * H6) >> 10)
++              * (((var * (s32)H3) >> 11) + (s32)32768)) >> 10)
++              + (s32)2097152) * H2 + 8192) >> 14);
++      var -= ((((var >> 15) * (var >> 15)) >> 7) * (s32)H1) >> 4;
+       return var >> 12;
+ };
diff --git a/queue-4.11/iio-dac-ad7303-fix-channel-description.patch b/queue-4.11/iio-dac-ad7303-fix-channel-description.patch
new file mode 100644 (file)
index 0000000..0a436dc
--- /dev/null
@@ -0,0 +1,35 @@
+From ce420fd4251809b4c3119b3b20c8b13bd8eba150 Mon Sep 17 00:00:00 2001
+From: Pavel Roskin <plroskin@gmail.com>
+Date: Thu, 13 Apr 2017 14:54:23 -0700
+Subject: iio: dac: ad7303: fix channel description
+
+From: Pavel Roskin <plroskin@gmail.com>
+
+commit ce420fd4251809b4c3119b3b20c8b13bd8eba150 upstream.
+
+realbits, storagebits and shift should be numbers, not ASCII characters.
+
+Signed-off-by: Pavel Roskin <plroskin@gmail.com>
+Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/dac/ad7303.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/dac/ad7303.c
++++ b/drivers/iio/dac/ad7303.c
+@@ -184,9 +184,9 @@ static const struct iio_chan_spec_ext_in
+       .address = (chan),                                      \
+       .scan_type = {                                          \
+               .sign = 'u',                                    \
+-              .realbits = '8',                                \
+-              .storagebits = '8',                             \
+-              .shift = '0',                                   \
++              .realbits = 8,                                  \
++              .storagebits = 8,                               \
++              .shift = 0,                                     \
+       },                                                      \
+       .ext_info = ad7303_ext_info,                            \
+ }
diff --git a/queue-4.11/iio-stm32-trigger-fix-sampling_frequency-read.patch b/queue-4.11/iio-stm32-trigger-fix-sampling_frequency-read.patch
new file mode 100644 (file)
index 0000000..db8162d
--- /dev/null
@@ -0,0 +1,59 @@
+From 77a9febfd81f9e8550d09dc76e8e9c06307b7aca Mon Sep 17 00:00:00 2001
+From: Fabrice Gasnier <fabrice.gasnier@st.com>
+Date: Fri, 7 Apr 2017 13:53:46 +0200
+Subject: iio: stm32 trigger: fix sampling_frequency read
+
+From: Fabrice Gasnier <fabrice.gasnier@st.com>
+
+commit 77a9febfd81f9e8550d09dc76e8e9c06307b7aca upstream.
+
+When prescaler (PSC) is 0, it means div factor is 1: counter clock
+frequency is equal to input clk / (PSC + 1).
+When reload value is 8 for example, counter counts 9 cycles, from 0 to 8.
+This is handled in frequency write routine, by writing respectively:
+- prescaler - 1 to PSC
+- reload value - 1 to ARR
+This fix does the opposite when reading the frequency from PSC and ARR:
+- prescaler is PSC + 1
+- reload value is ARR + 1
+
+Thus, PSC may be 0, depending on requested sampling frequency (div 1).
+In this case, reading freq wrongly reports 0, instead of computing and
+reporting correct value.
+Remove test on !psc and !arr.
+
+Small test on stm32f4 (example on tim1_trgo), before this fix:
+$ cd /sys/bus/iio/devices/triggerX
+$ echo 10000 > sampling_frequency
+$ cat sampling_frequency
+0
+
+After this fix:
+$ echo 10000 > sampling_frequency
+$ cat sampling_frequency
+10000
+
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/trigger/stm32-timer-trigger.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/trigger/stm32-timer-trigger.c
++++ b/drivers/iio/trigger/stm32-timer-trigger.c
+@@ -152,10 +152,10 @@ static ssize_t stm32_tt_read_frequency(s
+       regmap_read(priv->regmap, TIM_PSC, &psc);
+       regmap_read(priv->regmap, TIM_ARR, &arr);
+-      if (psc && arr && (cr1 & TIM_CR1_CEN)) {
++      if (cr1 & TIM_CR1_CEN) {
+               freq = (unsigned long long)clk_get_rate(priv->clk);
+-              do_div(freq, psc);
+-              do_div(freq, arr);
++              do_div(freq, psc + 1);
++              do_div(freq, arr + 1);
+       }
+       return sprintf(buf, "%d\n", (unsigned int)freq);
diff --git a/queue-4.11/of-fdt-add-missing-allocation-failure-check.patch b/queue-4.11/of-fdt-add-missing-allocation-failure-check.patch
new file mode 100644 (file)
index 0000000..ef14d28
--- /dev/null
@@ -0,0 +1,34 @@
+From 49e67dd17649b60b4d54966e18ec9c80198227f0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 17 May 2017 17:29:09 +0200
+Subject: of: fdt: add missing allocation-failure check
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 49e67dd17649b60b4d54966e18ec9c80198227f0 upstream.
+
+The memory allocator passed to __unflatten_device_tree() (e.g. a wrapped
+kzalloc) can fail so add the missing sanity check to avoid dereferencing
+a NULL pointer.
+
+Fixes: fe14042358fa ("of/flattree: Refactor unflatten_device_tree and add fdt_unflatten_tree")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/fdt.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -505,6 +505,9 @@ static void *__unflatten_device_tree(con
+       /* Allocate memory for the expanded device tree */
+       mem = dt_alloc(size + 4, __alignof__(struct device_node));
++      if (!mem)
++              return NULL;
++
+       memset(mem, 0, size);
+       *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
diff --git a/queue-4.11/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch b/queue-4.11/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch
new file mode 100644 (file)
index 0000000..8b81fe7
--- /dev/null
@@ -0,0 +1,37 @@
+From b8475cbee5ab2eac05f9cd5dbcc94c453d3cbf10 Mon Sep 17 00:00:00 2001
+From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+Date: Mon, 17 Apr 2017 20:29:17 -0400
+Subject: of: fix "/cpus" reference leak in of_numa_parse_cpu_nodes()
+
+From: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+
+commit b8475cbee5ab2eac05f9cd5dbcc94c453d3cbf10 upstream.
+
+The call to of_find_node_by_path("/cpus") returns the cpus device_node
+with its reference count incremented. There is no matching of_node_put()
+call in of_numa_parse_cpu_nodes() which results in a leaked reference
+to the "/cpus" node.
+
+This patch adds an of_node_put() to release the reference.
+
+fixes: 298535c00a2c ("of, numa: Add NUMA of binding implementation.")
+Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+Acked-by: David Daney <david.daney@cavium.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/of_numa.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/of/of_numa.c
++++ b/drivers/of/of_numa.c
+@@ -57,6 +57,8 @@ static void __init of_numa_parse_cpu_nod
+               else
+                       node_set(nid, numa_nodes_parsed);
+       }
++
++      of_node_put(cpus);
+ }
+ static int __init of_numa_parse_memory_nodes(void)
diff --git a/queue-4.11/of-fix-sparse-warning-in-of_pci_range_parser_one.patch b/queue-4.11/of-fix-sparse-warning-in-of_pci_range_parser_one.patch
new file mode 100644 (file)
index 0000000..2e397c7
--- /dev/null
@@ -0,0 +1,36 @@
+From eb3100365791b06242b8bb5c3c2854ba41dabfbc Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Thu, 4 May 2017 12:34:30 -0500
+Subject: of: fix sparse warning in of_pci_range_parser_one
+
+From: Rob Herring <robh@kernel.org>
+
+commit eb3100365791b06242b8bb5c3c2854ba41dabfbc upstream.
+
+sparse gives the following warning for 'pci_space':
+
+../drivers/of/address.c:266:26: warning: incorrect type in assignment (different base types)
+../drivers/of/address.c:266:26:    expected unsigned int [unsigned] [usertype] pci_space
+../drivers/of/address.c:266:26:    got restricted __be32 const [usertype] <noident>
+
+It appears that pci_space is only ever accessed on powerpc, so the endian
+swap is often not needed.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/address.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -263,7 +263,7 @@ struct of_pci_range *of_pci_range_parser
+       if (!parser->range || parser->range + parser->np > parser->end)
+               return NULL;
+-      range->pci_space = parser->range[0];
++      range->pci_space = be32_to_cpup(parser->range);
+       range->flags = of_bus_pci_get_flags(parser->range);
+       range->pci_addr = of_read_number(parser->range + 1, ns);
+       range->cpu_addr = of_translate_address(parser->node,
diff --git a/queue-4.11/ohci-pci-add-qemu-quirk.patch b/queue-4.11/ohci-pci-add-qemu-quirk.patch
new file mode 100644 (file)
index 0000000..6180fdf
--- /dev/null
@@ -0,0 +1,83 @@
+From 21a60f6e65181cad64fd66ccc8080d413721ba27 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Mon, 20 Mar 2017 09:11:49 +0100
+Subject: ohci-pci: add qemu quirk
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+commit 21a60f6e65181cad64fd66ccc8080d413721ba27 upstream.
+
+On a loaded virtualization host (dozen guests booting at the same time)
+it may happen that the ohci controller emulation doesn't manage to do
+timely frame processing, with the result that the io watchdog fires and
+considers the controller being dead, even though it's only the emulation
+being unusual slow due to the load peak.
+
+So, add a quirk for qemu and don't use the watchdog in case we figure we
+are running on emulated ohci.  The virtual ohci controller masquerades
+as apple ohci controller, but we can identify it by subsystem id.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ohci-hcd.c |    3 ++-
+ drivers/usb/host/ohci-pci.c |   16 ++++++++++++++++
+ drivers/usb/host/ohci.h     |    1 +
+ 3 files changed, 19 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -231,7 +231,8 @@ static int ohci_urb_enqueue (
+               /* Start up the I/O watchdog timer, if it's not running */
+               if (!timer_pending(&ohci->io_watchdog) &&
+-                              list_empty(&ohci->eds_in_use)) {
++                              list_empty(&ohci->eds_in_use) &&
++                              !(ohci->flags & OHCI_QUIRK_QEMU)) {
+                       ohci->prev_frame_no = ohci_frame_no(ohci);
+                       mod_timer(&ohci->io_watchdog,
+                                       jiffies + IO_WATCHDOG_DELAY);
+--- a/drivers/usb/host/ohci-pci.c
++++ b/drivers/usb/host/ohci-pci.c
+@@ -164,6 +164,15 @@ static int ohci_quirk_amd700(struct usb_
+       return 0;
+ }
++static int ohci_quirk_qemu(struct usb_hcd *hcd)
++{
++      struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++      ohci->flags |= OHCI_QUIRK_QEMU;
++      ohci_dbg(ohci, "enabled qemu quirk\n");
++      return 0;
++}
++
+ /* List of quirks for OHCI */
+ static const struct pci_device_id ohci_pci_quirks[] = {
+       {
+@@ -214,6 +223,13 @@ static const struct pci_device_id ohci_p
+               PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
+               .driver_data = (unsigned long)ohci_quirk_amd700,
+       },
++      {
++              .vendor         = PCI_VENDOR_ID_APPLE,
++              .device         = 0x003f,
++              .subvendor      = PCI_SUBVENDOR_ID_REDHAT_QUMRANET,
++              .subdevice      = PCI_SUBDEVICE_ID_QEMU,
++              .driver_data    = (unsigned long)ohci_quirk_qemu,
++      },
+       /* FIXME for some of the early AMD 760 southbridges, OHCI
+        * won't work at all.  blacklist them.
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -418,6 +418,7 @@ struct ohci_hcd {
+ #define       OHCI_QUIRK_AMD_PLL      0x200                   /* AMD PLL quirk*/
+ #define       OHCI_QUIRK_AMD_PREFETCH 0x400                   /* pre-fetch for ISO transfer */
+ #define       OHCI_QUIRK_GLOBAL_SUSPEND       0x800           /* must suspend ports */
++#define       OHCI_QUIRK_QEMU         0x1000                  /* relax timing expectations */
+       // there are also chip quirks/bugs in init logic
diff --git a/queue-4.11/proc-fix-unbalanced-hard-link-numbers.patch b/queue-4.11/proc-fix-unbalanced-hard-link-numbers.patch
new file mode 100644 (file)
index 0000000..d4be790
--- /dev/null
@@ -0,0 +1,33 @@
+From d66bb1607e2d8d384e53f3d93db5c18483c8c4f7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 28 Apr 2017 15:00:15 +0200
+Subject: proc: Fix unbalanced hard link numbers
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit d66bb1607e2d8d384e53f3d93db5c18483c8c4f7 upstream.
+
+proc_create_mount_point() forgot to increase the parent's nlink, and
+it resulted in unbalanced hard link numbers, e.g. /proc/fs shows one
+less than expected.
+
+Fixes: eb6d38d5427b ("proc: Allow creating permanently empty directories...")
+Reported-by: Tristan Ye <tristan.ye@suse.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/generic.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/proc/generic.c
++++ b/fs/proc/generic.c
+@@ -472,6 +472,7 @@ struct proc_dir_entry *proc_create_mount
+               ent->data = NULL;
+               ent->proc_fops = NULL;
+               ent->proc_iops = NULL;
++              parent->nlink++;
+               if (proc_register(parent, ent) < 0) {
+                       kfree(ent);
+                       parent->nlink--;
diff --git a/queue-4.11/scsi-lpfc-fix-panic-on-bfs-configuration.patch b/queue-4.11/scsi-lpfc-fix-panic-on-bfs-configuration.patch
new file mode 100644 (file)
index 0000000..8752a3a
--- /dev/null
@@ -0,0 +1,139 @@
+From 4492b739c9ccfaf828bd7c02dc779ec2a5e55ff4 Mon Sep 17 00:00:00 2001
+From: James Smart <jsmart2021@gmail.com>
+Date: Thu, 27 Apr 2017 15:08:26 -0700
+Subject: scsi: lpfc: Fix panic on BFS configuration
+
+From: James Smart <jsmart2021@gmail.com>
+
+commit 4492b739c9ccfaf828bd7c02dc779ec2a5e55ff4 upstream.
+
+To select the appropriate shost template, the driver is issuing a
+mailbox command to retrieve the wwn. Turns out the sending of the
+command precedes the reset of the function.  On SLI-4 adapters, this is
+inconsequential as the mailbox command location is specified by dma via
+the BMBX register. However, on SLI-3 adapters, the location of the
+mailbox command submission area changes. When the function is first
+powered on or reset, the cmd is submitted via PCI bar memory. Later the
+driver changes the function config to use host memory and DMA. The
+request to start a mailbox command is the same, a simple doorbell write,
+regardless of submission area.  So.. if there has not been a boot driver
+run against the adapter, the mailbox command works as defaults are
+ok. But, if the boot driver has configured the card and, and if no
+platform pci function/slot reset occurs as the os starts, the mailbox
+command will fail. The SLI-3 device will use the stale boot driver dma
+location. This can cause PCI eeh errors.
+
+Fix is to reset the sli-3 function before sending the mailbox command,
+thus synchronizing the function/driver on mailbox location.
+
+Note: The fix uses routines that are typically invoked later in the call
+flow to reset the sli-3 device. The issue in using those routines is
+that the normal (non-fix) flow does additional initialization, namely
+the allocation of the pport structure. So, rather than significantly
+reworking the initialization flow so that the pport is alloc'd first,
+pointer checks are added to work around it. Checks are limited to the
+routines invoked by a sli-3 adapter (s3 routines) as this fix/early call
+is only invoked on a sli3 adapter. Nothing changes post the
+fix. Subsequent initialization, and another adapter reset, still occur -
+both on sli-3 and sli-4 adapters.
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Fixes: 96418b5e2c88 ("scsi: lpfc: Fix eh_deadline setting for sli3 adapters.")
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/lpfc/lpfc_crtn.h |    1 +
+ drivers/scsi/lpfc/lpfc_init.c |    7 +++++++
+ drivers/scsi/lpfc/lpfc_sli.c  |   19 ++++++++++++-------
+ 3 files changed, 20 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -289,6 +289,7 @@ int lpfc_selective_reset(struct lpfc_hba
+ void lpfc_reset_barrier(struct lpfc_hba *);
+ int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
+ int lpfc_sli_brdkill(struct lpfc_hba *);
++int lpfc_sli_chipset_init(struct lpfc_hba *phba);
+ int lpfc_sli_brdreset(struct lpfc_hba *);
+ int lpfc_sli_brdrestart(struct lpfc_hba *);
+ int lpfc_sli_hba_setup(struct lpfc_hba *);
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -3563,6 +3563,13 @@ lpfc_get_wwpn(struct lpfc_hba *phba)
+       LPFC_MBOXQ_t *mboxq;
+       MAILBOX_t *mb;
++      if (phba->sli_rev < LPFC_SLI_REV4) {
++              /* Reset the port first */
++              lpfc_sli_brdrestart(phba);
++              rc = lpfc_sli_chipset_init(phba);
++              if (rc)
++                      return (uint64_t)-1;
++      }
+       mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
+                                               GFP_KERNEL);
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -4204,13 +4204,16 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
+       /* Reset HBA */
+       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                       "0325 Reset HBA Data: x%x x%x\n",
+-                      phba->pport->port_state, psli->sli_flag);
++                      (phba->pport) ? phba->pport->port_state : 0,
++                      psli->sli_flag);
+       /* perform board reset */
+       phba->fc_eventTag = 0;
+       phba->link_events = 0;
+-      phba->pport->fc_myDID = 0;
+-      phba->pport->fc_prevDID = 0;
++      if (phba->pport) {
++              phba->pport->fc_myDID = 0;
++              phba->pport->fc_prevDID = 0;
++      }
+       /* Turn off parity checking and serr during the physical reset */
+       pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
+@@ -4336,7 +4339,8 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *
+       /* Restart HBA */
+       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                       "0337 Restart HBA Data: x%x x%x\n",
+-                      phba->pport->port_state, psli->sli_flag);
++                      (phba->pport) ? phba->pport->port_state : 0,
++                      psli->sli_flag);
+       word0 = 0;
+       mb = (MAILBOX_t *) &word0;
+@@ -4350,7 +4354,7 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *
+       readl(to_slim); /* flush */
+       /* Only skip post after fc_ffinit is completed */
+-      if (phba->pport->port_state)
++      if (phba->pport && phba->pport->port_state)
+               word0 = 1;      /* This is really setting up word1 */
+       else
+               word0 = 0;      /* This is really setting up word1 */
+@@ -4359,7 +4363,8 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *
+       readl(to_slim); /* flush */
+       lpfc_sli_brdreset(phba);
+-      phba->pport->stopped = 0;
++      if (phba->pport)
++              phba->pport->stopped = 0;
+       phba->link_state = LPFC_INIT_START;
+       phba->hba_flag = 0;
+       spin_unlock_irq(&phba->hbalock);
+@@ -4446,7 +4451,7 @@ lpfc_sli_brdrestart(struct lpfc_hba *phb
+  * iteration, the function will restart the HBA again. The function returns
+  * zero if HBA successfully restarted else returns negative error code.
+  **/
+-static int
++int
+ lpfc_sli_chipset_init(struct lpfc_hba *phba)
+ {
+       uint32_t status, i = 0;
index 501928ba27ab49a298c182d281e17a17de8ffca0..e39905a295385877d4b96f832c145ab02528f814 100644 (file)
@@ -48,3 +48,28 @@ s390-kdump-add-final-note.patch
 s390-cputime-fix-incorrect-system-time.patch
 ath9k_htc-add-support-of-airties-1eda-2315-ar9271-device.patch
 ath9k_htc-fix-null-deref-at-probe.patch
+drm-amdgpu-make-display-watermark-calculations-more-accurate.patch
+drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch
+drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch
+drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch
+drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch
+drm-nouveau-kms-nv50-fix-source-rect-only-plane-updates.patch
+drm-nouveau-kms-nv50-skip-core-channel-cursor-update-on-position-only-changes.patch
+drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch
+drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch
+drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch
+drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch
+gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch
+cdc-acm-fix-possible-invalid-access-when-processing-notification.patch
+ohci-pci-add-qemu-quirk.patch
+cxl-force-context-lock-during-eeh-flow.patch
+cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch
+proc-fix-unbalanced-hard-link-numbers.patch
+of-fix-sparse-warning-in-of_pci_range_parser_one.patch
+of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch
+of-fdt-add-missing-allocation-failure-check.patch
+ibmvscsis-do-not-send-aborted-task-response.patch
+scsi-lpfc-fix-panic-on-bfs-configuration.patch
+iio-dac-ad7303-fix-channel-description.patch
+iio-bmp280-core.c-fix-error-in-humidity-calculation.patch
+iio-stm32-trigger-fix-sampling_frequency-read.patch