From: Greg Kroah-Hartman Date: Mon, 22 May 2017 17:04:29 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.55~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=899c9bca1e54ab7d32f39f92cc2016d1ef83760e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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-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 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 --- diff --git a/queue-4.9/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch b/queue-4.9/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch new file mode 100644 index 00000000000..219bcd95063 --- /dev/null +++ b/queue-4.9/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch @@ -0,0 +1,52 @@ +From 1bb9914e1730417d530de9ed37e59efdc647146b Mon Sep 17 00:00:00 2001 +From: Tobias Herzog +Date: Thu, 30 Mar 2017 22:15:10 +0200 +Subject: cdc-acm: fix possible invalid access when processing notification + +From: Tobias Herzog + +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 +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -311,6 +311,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)) { +@@ -347,11 +353,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.9/cxl-force-context-lock-during-eeh-flow.patch b/queue-4.9/cxl-force-context-lock-during-eeh-flow.patch new file mode 100644 index 00000000000..51741872d3e --- /dev/null +++ b/queue-4.9/cxl-force-context-lock-during-eeh-flow.patch @@ -0,0 +1,95 @@ +From ea9a26d117cf0637c71d3e0076f4a124bf5859df Mon Sep 17 00:00:00 2001 +From: Vaibhav Jain +Date: Thu, 27 Apr 2017 10:53:25 +0530 +Subject: cxl: Force context lock during EEH flow + +From: Vaibhav Jain + +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 +Signed-off-by: Vaibhav Jain +Acked-by: Frederic Barrat +Reviewed-by: Matthew R. Ochs +Tested-by: Uma Krishnan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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: +@@ -1893,6 +1894,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; +@@ -1911,6 +1919,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.9/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch b/queue-4.9/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch new file mode 100644 index 00000000000..32864e45180 --- /dev/null +++ b/queue-4.9/cxl-route-eeh-events-to-all-drivers-in-cxl_pci_error_detected.patch @@ -0,0 +1,68 @@ +From 4f58f0bf155e87dda31a3088b1e107fa9dd79f0e Mon Sep 17 00:00:00 2001 +From: Vaibhav Jain +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 + +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 +Reviewed-by: Andrew Donnellan +Acked-by: Frederic Barrat +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1779,7 +1779,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. +@@ -1884,15 +1884,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.9/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch b/queue-4.9/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch new file mode 100644 index 00000000000..222c959c1d4 --- /dev/null +++ b/queue-4.9/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch @@ -0,0 +1,51 @@ +From effaf848b957fbf72a3b6a1ad87f5e031eda0b75 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +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 + +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 +Cc: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1050,7 +1050,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) { +@@ -1162,6 +1162,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 */ +@@ -1191,6 +1193,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.9/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch b/queue-4.9/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch new file mode 100644 index 00000000000..a037c942fdc --- /dev/null +++ b/queue-4.9/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch @@ -0,0 +1,150 @@ +From e190ed1ea7458e446230de4113cc5d53b8dc4ec8 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Wed, 29 Mar 2017 22:09:12 +0200 +Subject: drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations. + +From: Mario Kleiner + +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 +Signed-off-by: Mario Kleiner +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1173,23 +1173,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 +@@ -1140,23 +1140,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 +@@ -932,23 +932,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 +@@ -1094,23 +1094,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.9/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch b/queue-4.9/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch new file mode 100644 index 00000000000..18b62b939d0 --- /dev/null +++ b/queue-4.9/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch @@ -0,0 +1,182 @@ +From d63c277dc672e0c568481af043359420fa9d4736 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Wed, 29 Mar 2017 22:09:11 +0200 +Subject: drm/amdgpu: Make display watermark calculations more accurate + +From: Mario Kleiner + +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 +Signed-off-by: Mario Kleiner +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1297,14 +1297,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) { +@@ -1319,7 +1319,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) +@@ -1358,7 +1358,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 +@@ -1264,14 +1264,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) { +@@ -1286,7 +1286,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) +@@ -1325,7 +1325,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 +@@ -1057,7 +1057,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; +@@ -1067,8 +1067,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; + +@@ -1087,7 +1087,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) +@@ -1114,7 +1114,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 +@@ -1218,14 +1218,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) { +@@ -1240,7 +1240,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) +@@ -1279,7 +1279,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.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch b/queue-4.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch new file mode 100644 index 00000000000..50f3534bd66 --- /dev/null +++ b/queue-4.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch @@ -0,0 +1,40 @@ +From ac799acaa4d8db4f7dcd968b15c9596c80a4677f Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +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 + +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 +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch b/queue-4.9/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch new file mode 100644 index 00000000000..dac1d3abd5e --- /dev/null +++ b/queue-4.9/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch @@ -0,0 +1,66 @@ +From e4311ee51d1e2676001b2d8fcefd92bdd79aad85 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 17:33:39 +1000 +Subject: drm/nouveau/therm: remove ineffective workarounds for alarm bugs + +From: Ben Skeggs + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -130,7 +130,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.9/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch b/queue-4.9/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch new file mode 100644 index 00000000000..9de8848baa9 --- /dev/null +++ b/queue-4.9/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch @@ -0,0 +1,31 @@ +From 3733bd8b407211739e72d051e5f30ad82a52c4bc Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 16:53:42 +1000 +Subject: drm/nouveau/tmr: ack interrupt before processing alarms + +From: Ben Skeggs + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch b/queue-4.9/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch new file mode 100644 index 00000000000..ba5c6e0300a --- /dev/null +++ b/queue-4.9/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch @@ -0,0 +1,50 @@ +From 330bdf62fe6a6c5b99a647f7bf7157107c9348b3 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch b/queue-4.9/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch new file mode 100644 index 00000000000..462e7cacbf0 --- /dev/null +++ b/queue-4.9/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch @@ -0,0 +1,49 @@ +From 9fc64667ee48c9a25e7dca1a6bcb6906fec5bcc5 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch b/queue-4.9/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch new file mode 100644 index 00000000000..8141f9704da --- /dev/null +++ b/queue-4.9/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch @@ -0,0 +1,63 @@ +From 1b0f84380b10ee97f7d2dd191294de9017e94d1d Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch b/queue-4.9/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch new file mode 100644 index 00000000000..4b747e2e1c9 --- /dev/null +++ b/queue-4.9/gpio-omap-return-error-if-requested-debounce-time-is-not-possible.patch @@ -0,0 +1,94 @@ +From 83977443938122baeed28dc9f078db3da9855f7c Mon Sep 17 00:00:00 2001 +From: David Rivshin +Date: Mon, 24 Apr 2017 18:56:50 -0400 +Subject: gpio: omap: return error if requested debounce time is not possible + +From: David Rivshin + +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 +Acked-by: Grygorii Strashko +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + * = (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 void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value) diff --git a/queue-4.9/ibmvscsis-do-not-send-aborted-task-response.patch b/queue-4.9/ibmvscsis-do-not-send-aborted-task-response.patch new file mode 100644 index 00000000000..01568f8e5c4 --- /dev/null +++ b/queue-4.9/ibmvscsis-do-not-send-aborted-task-response.patch @@ -0,0 +1,242 @@ +From 25e78531268e9240fc594ce76587601b873d37c9 Mon Sep 17 00:00:00 2001 +From: "Bryant G. Ly" +Date: Fri, 5 May 2017 14:17:15 -0500 +Subject: ibmvscsis: Do not send aborted task response + +From: Bryant G. Ly + +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 +Signed-off-by: Michael Cyr +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1169,6 +1169,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; +@@ -1748,45 +1749,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) { + /* +@@ -2707,6 +2742,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); +@@ -3578,9 +3614,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) { +@@ -3659,11 +3706,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; +@@ -3671,8 +3735,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 +@@ -167,10 +167,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.9/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch b/queue-4.9/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch new file mode 100644 index 00000000000..afc69d182e3 --- /dev/null +++ b/queue-4.9/iio-bmp280-core.c-fix-error-in-humidity-calculation.patch @@ -0,0 +1,44 @@ +From ed3730c435f1a9f9559ed7762035d22d8a95adfe Mon Sep 17 00:00:00 2001 +From: Andreas Klinger +Date: Mon, 10 Apr 2017 19:00:01 +0200 +Subject: IIO: bmp280-core.c: fix error in humidity calculation + +From: Andreas Klinger + +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 +Acked-by: Linus Walleij +Reviewed-by: Matt Ranostay +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/iio-dac-ad7303-fix-channel-description.patch b/queue-4.9/iio-dac-ad7303-fix-channel-description.patch new file mode 100644 index 00000000000..0a436dc57cc --- /dev/null +++ b/queue-4.9/iio-dac-ad7303-fix-channel-description.patch @@ -0,0 +1,35 @@ +From ce420fd4251809b4c3119b3b20c8b13bd8eba150 Mon Sep 17 00:00:00 2001 +From: Pavel Roskin +Date: Thu, 13 Apr 2017 14:54:23 -0700 +Subject: iio: dac: ad7303: fix channel description + +From: Pavel Roskin + +commit ce420fd4251809b4c3119b3b20c8b13bd8eba150 upstream. + +realbits, storagebits and shift should be numbers, not ASCII characters. + +Signed-off-by: Pavel Roskin +Reviewed-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/of-fdt-add-missing-allocation-failure-check.patch b/queue-4.9/of-fdt-add-missing-allocation-failure-check.patch new file mode 100644 index 00000000000..ef14d289022 --- /dev/null +++ b/queue-4.9/of-fdt-add-missing-allocation-failure-check.patch @@ -0,0 +1,34 @@ +From 49e67dd17649b60b4d54966e18ec9c80198227f0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 17 May 2017 17:29:09 +0200 +Subject: of: fdt: add missing allocation-failure check + +From: Johan Hovold + +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 +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch b/queue-4.9/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch new file mode 100644 index 00000000000..8b81fe7fe47 --- /dev/null +++ b/queue-4.9/of-fix-cpus-reference-leak-in-of_numa_parse_cpu_nodes.patch @@ -0,0 +1,37 @@ +From b8475cbee5ab2eac05f9cd5dbcc94c453d3cbf10 Mon Sep 17 00:00:00 2001 +From: Tyrel Datwyler +Date: Mon, 17 Apr 2017 20:29:17 -0400 +Subject: of: fix "/cpus" reference leak in of_numa_parse_cpu_nodes() + +From: Tyrel Datwyler + +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 +Acked-by: David Daney +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/of-fix-sparse-warning-in-of_pci_range_parser_one.patch b/queue-4.9/of-fix-sparse-warning-in-of_pci_range_parser_one.patch new file mode 100644 index 00000000000..2e397c7d0fc --- /dev/null +++ b/queue-4.9/of-fix-sparse-warning-in-of_pci_range_parser_one.patch @@ -0,0 +1,36 @@ +From eb3100365791b06242b8bb5c3c2854ba41dabfbc Mon Sep 17 00:00:00 2001 +From: Rob Herring +Date: Thu, 4 May 2017 12:34:30 -0500 +Subject: of: fix sparse warning in of_pci_range_parser_one + +From: Rob Herring + +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] + +It appears that pci_space is only ever accessed on powerpc, so the endian +swap is often not needed. + +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/ohci-pci-add-qemu-quirk.patch b/queue-4.9/ohci-pci-add-qemu-quirk.patch new file mode 100644 index 00000000000..6180fdf5ce3 --- /dev/null +++ b/queue-4.9/ohci-pci-add-qemu-quirk.patch @@ -0,0 +1,83 @@ +From 21a60f6e65181cad64fd66ccc8080d413721ba27 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 20 Mar 2017 09:11:49 +0100 +Subject: ohci-pci: add qemu quirk + +From: Gerd Hoffmann + +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 +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/proc-fix-unbalanced-hard-link-numbers.patch b/queue-4.9/proc-fix-unbalanced-hard-link-numbers.patch new file mode 100644 index 00000000000..7e9ad520bf1 --- /dev/null +++ b/queue-4.9/proc-fix-unbalanced-hard-link-numbers.patch @@ -0,0 +1,33 @@ +From d66bb1607e2d8d384e53f3d93db5c18483c8c4f7 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 28 Apr 2017 15:00:15 +0200 +Subject: proc: Fix unbalanced hard link numbers + +From: Takashi Iwai + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Eric W. Biederman +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/generic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -471,6 +471,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.9/series b/queue-4.9/series index d8c61b9d35b..c782347cd80 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -44,3 +44,24 @@ 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-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 +iio-dac-ad7303-fix-channel-description.patch +iio-bmp280-core.c-fix-error-in-humidity-calculation.patch