--- /dev/null
+From a21211672c9a1d730a39aa65d4a5b3414700adfb Mon Sep 17 00:00:00 2001
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Date: Wed, 23 Mar 2016 21:07:39 -0700
+Subject: ACPI / processor: Request native thermal interrupt handling via _OSC
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+commit a21211672c9a1d730a39aa65d4a5b3414700adfb upstream.
+
+There are several reports of freeze on enabling HWP (Hardware PStates)
+feature on Skylake-based systems by the Intel P-states driver. The root
+cause is identified as the HWP interrupts causing BIOS code to freeze.
+
+HWP interrupts use the thermal LVT which can be handled by Linux
+natively, but on the affected Skylake-based systems SMM will respond
+to it by default. This is a problem for several reasons:
+ - On the affected systems the SMM thermal LVT handler is broken (it
+ will crash when invoked) and a BIOS update is necessary to fix it.
+ - With thermal interrupt handled in SMM we lose all of the reporting
+ features of the arch/x86/kernel/cpu/mcheck/therm_throt driver.
+ - Some thermal drivers like x86-package-temp depend on the thermal
+ threshold interrupts signaled via the thermal LVT.
+ - The HWP interrupts are useful for debugging and tuning
+ performance (if the kernel can handle them).
+The native handling of thermal interrupts needs to be enabled
+because of that.
+
+This requires some way to tell SMM that the OS can handle thermal
+interrupts. That can be done by using _OSC/_PDC in processor
+scope very early during ACPI initialization.
+
+The meaning of _OSC/_PDC bit 12 in processor scope is whether or
+not the OS supports native handling of interrupts for Collaborative
+Processor Performance Control (CPPC) notifications. Since on
+HWP-capable systems CPPC is a firmware interface to HWP, setting
+this bit effectively tells the firmware that the OS will handle
+thermal interrupts natively going forward.
+
+For details on _OSC/_PDC refer to:
+http://www.intel.com/content/www/us/en/standards/processor-vendor-specific-acpi-specification.html
+
+To implement the _OSC/_PDC handshake as described, introduce a new
+function, acpi_early_processor_osc(), that walks the ACPI
+namespace looking for ACPI processor objects and invokes _OSC for
+them with bit 12 in the capabilities buffer set and terminates the
+namespace walk on the first success.
+
+Also modify intel_thermal_interrupt() to clear HWP status bits in
+the HWP_STATUS MSR to acknowledge HWP interrupts (which prevents
+them from firing continuously).
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+[ rjw: Subject & changelog, function rename ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/mcheck/therm_throt.c | 3 +
+ drivers/acpi/acpi_processor.c | 52 +++++++++++++++++++++++++++++++
+ drivers/acpi/bus.c | 3 +
+ drivers/acpi/internal.h | 6 +++
+ 4 files changed, 64 insertions(+)
+
+--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
++++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
+@@ -385,6 +385,9 @@ static void intel_thermal_interrupt(void
+ {
+ __u64 msr_val;
+
++ if (static_cpu_has(X86_FEATURE_HWP))
++ wrmsrl_safe(MSR_HWP_STATUS, 0);
++
+ rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
+
+ /* Check for violation of core thermal thresholds*/
+--- a/drivers/acpi/acpi_processor.c
++++ b/drivers/acpi/acpi_processor.c
+@@ -491,6 +491,58 @@ static void acpi_processor_remove(struct
+ }
+ #endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
++#ifdef CONFIG_X86
++static bool acpi_hwp_native_thermal_lvt_set;
++static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
++ u32 lvl,
++ void *context,
++ void **rv)
++{
++ u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
++ u32 capbuf[2];
++ struct acpi_osc_context osc_context = {
++ .uuid_str = sb_uuid_str,
++ .rev = 1,
++ .cap.length = 8,
++ .cap.pointer = capbuf,
++ };
++
++ if (acpi_hwp_native_thermal_lvt_set)
++ return AE_CTRL_TERMINATE;
++
++ capbuf[0] = 0x0000;
++ capbuf[1] = 0x1000; /* set bit 12 */
++
++ if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
++ if (osc_context.ret.pointer && osc_context.ret.length > 1) {
++ u32 *capbuf_ret = osc_context.ret.pointer;
++
++ if (capbuf_ret[1] & 0x1000) {
++ acpi_handle_info(handle,
++ "_OSC native thermal LVT Acked\n");
++ acpi_hwp_native_thermal_lvt_set = true;
++ }
++ }
++ kfree(osc_context.ret.pointer);
++ }
++
++ return AE_OK;
++}
++
++void __init acpi_early_processor_osc(void)
++{
++ if (boot_cpu_has(X86_FEATURE_HWP)) {
++ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
++ ACPI_UINT32_MAX,
++ acpi_hwp_native_thermal_lvt_osc,
++ NULL, NULL, NULL);
++ acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
++ acpi_hwp_native_thermal_lvt_osc,
++ NULL, NULL);
++ }
++}
++#endif
++
+ /*
+ * The following ACPI IDs are known to be suitable for representing as
+ * processor devices.
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -1004,6 +1004,9 @@ static int __init acpi_bus_init(void)
+ goto error1;
+ }
+
++ /* Set capability bits for _OSC under processor scope */
++ acpi_early_processor_osc();
++
+ /*
+ * _OSC method may exist in module level code,
+ * so it must be run after ACPI_FULL_INITIALIZATION
+--- a/drivers/acpi/internal.h
++++ b/drivers/acpi/internal.h
+@@ -130,6 +130,12 @@ void acpi_early_processor_set_pdc(void);
+ static inline void acpi_early_processor_set_pdc(void) {}
+ #endif
+
++#ifdef CONFIG_X86
++void acpi_early_processor_osc(void);
++#else
++static inline void acpi_early_processor_osc(void) {}
++#endif
++
+ /* --------------------------------------------------------------------------
+ Embedded Controller
+ -------------------------------------------------------------------------- */
--- /dev/null
+From a41c8882592fb80458959b10e37632ce030b68ca Mon Sep 17 00:00:00 2001
+From: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Date: Thu, 28 Jan 2016 15:19:23 -0800
+Subject: drm/i915/skl: Fix DMC load on Skylake J0 and K0
+
+From: Mat Martineau <mathew.j.martineau@linux.intel.com>
+
+commit a41c8882592fb80458959b10e37632ce030b68ca upstream.
+
+The driver does not load firmware for unknown steppings, so these new
+steppings must be added to the list.
+
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/1454023163-25469-1-git-send-email-mathew.j.martineau@linux.intel.com
+Cc: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_csr.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/intel_csr.c
++++ b/drivers/gpu/drm/i915/intel_csr.c
+@@ -180,7 +180,8 @@ struct stepping_info {
+ static const struct stepping_info skl_stepping_info[] = {
+ {'A', '0'}, {'B', '0'}, {'C', '0'},
+ {'D', '0'}, {'E', '0'}, {'F', '0'},
+- {'G', '0'}, {'H', '0'}, {'I', '0'}
++ {'G', '0'}, {'H', '0'}, {'I', '0'},
++ {'J', '0'}, {'K', '0'}
+ };
+
+ static struct stepping_info bxt_stepping_info[] = {
--- /dev/null
+From 72676bb53f33fd0ef3a1484fc1ecfd306dc6ff40 Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Tue, 2 Feb 2016 16:57:18 -0800
+Subject: lib/test-string_helpers.c: fix and improve string_get_size() tests
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 72676bb53f33fd0ef3a1484fc1ecfd306dc6ff40 upstream.
+
+Recently added commit 564b026fbd0d ("string_helpers: fix precision loss
+for some inputs") fixed precision issues for string_get_size() and broke
+tests.
+
+Fix and improve them: test both STRING_UNITS_2 and STRING_UNITS_10 at a
+time, better failure reporting, test small an huge values.
+
+Fixes: 564b026fbd0d28e9 ("string_helpers: fix precision loss for some inputs")
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Cc: James Bottomley <JBottomley@Odin.com>
+Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/test-string_helpers.c | 67 +++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 49 insertions(+), 18 deletions(-)
+
+--- a/lib/test-string_helpers.c
++++ b/lib/test-string_helpers.c
+@@ -327,36 +327,67 @@ out:
+ }
+
+ #define string_get_size_maxbuf 16
+-#define test_string_get_size_one(size, blk_size, units, exp_result) \
++#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2) \
+ do { \
+- BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf); \
+- __test_string_get_size((size), (blk_size), (units), \
+- (exp_result)); \
++ BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf); \
++ BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf); \
++ __test_string_get_size((size), (blk_size), (exp_result10), \
++ (exp_result2)); \
+ } while (0)
+
+
+-static __init void __test_string_get_size(const u64 size, const u64 blk_size,
+- const enum string_size_units units,
+- const char *exp_result)
++static __init void test_string_get_size_check(const char *units,
++ const char *exp,
++ char *res,
++ const u64 size,
++ const u64 blk_size)
+ {
+- char buf[string_get_size_maxbuf];
+-
+- string_get_size(size, blk_size, units, buf, sizeof(buf));
+- if (!memcmp(buf, exp_result, strlen(exp_result) + 1))
++ if (!memcmp(res, exp, strlen(exp) + 1))
+ return;
+
+- buf[sizeof(buf) - 1] = '\0';
+- pr_warn("Test 'test_string_get_size_one' failed!\n");
+- pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n",
++ res[string_get_size_maxbuf - 1] = '\0';
++
++ pr_warn("Test 'test_string_get_size' failed!\n");
++ pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n",
+ size, blk_size, units);
+- pr_warn("expected: '%s', got '%s'\n", exp_result, buf);
++ pr_warn("expected: '%s', got '%s'\n", exp, res);
++}
++
++static __init void __test_string_get_size(const u64 size, const u64 blk_size,
++ const char *exp_result10,
++ const char *exp_result2)
++{
++ char buf10[string_get_size_maxbuf];
++ char buf2[string_get_size_maxbuf];
++
++ string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10));
++ string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2));
++
++ test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10,
++ size, blk_size);
++
++ test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2,
++ size, blk_size);
+ }
+
+ static __init void test_string_get_size(void)
+ {
+- test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB");
+- test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB");
+- test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B");
++ /* small values */
++ test_string_get_size_one(0, 512, "0 B", "0 B");
++ test_string_get_size_one(1, 512, "512 B", "512 B");
++ test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
++
++ /* normal values */
++ test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
++ test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
++ test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
++
++ /* weird block sizes */
++ test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
++
++ /* huge values */
++ test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
++ test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
+ }
+
+ static int __init test_string_helpers_init(void)
drm-i915-fix-edp-low-vswing-for-broadwell.patch
drm-i915-make-rps-ei-thresholds-multiple-of-25-on-snb-bdw.patch
drm-i915-fake-hdmi-live-status.patch
+acpi-processor-request-native-thermal-interrupt-handling-via-_osc.patch
+lib-test-string_helpers.c-fix-and-improve-string_get_size-tests.patch
+drm-i915-skl-fix-dmc-load-on-skylake-j0-and-k0.patch