diff --git a/patches/4.19/0001-surface-acpi.patch b/patches/4.19/0001-surface-acpi.patch index 772712027..c4747c0b0 100644 --- a/patches/4.19/0001-surface-acpi.patch +++ b/patches/4.19/0001-surface-acpi.patch @@ -1,7 +1,7 @@ From e9f55e5da497d27e0908cbffd3ecd0e8f1369ddb Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:43:58 +0200 -Subject: [PATCH 01/11] surface-acpi +Subject: [PATCH 01/12] surface-acpi --- drivers/acpi/acpica/dsopcode.c | 2 +- diff --git a/patches/4.19/0002-suspend.patch b/patches/4.19/0002-suspend.patch index 886e2581f..301a4f452 100644 --- a/patches/4.19/0002-suspend.patch +++ b/patches/4.19/0002-suspend.patch @@ -1,7 +1,7 @@ From e851005607738247775e43e9ac4336edd4c09516 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:45:42 +0200 -Subject: [PATCH 02/11] suspend +Subject: [PATCH 02/12] suspend --- drivers/nvme/host/nvme.h | 5 +++++ diff --git a/patches/4.19/0003-buttons.patch b/patches/4.19/0003-buttons.patch index 629f496f0..2be6bd214 100644 --- a/patches/4.19/0003-buttons.patch +++ b/patches/4.19/0003-buttons.patch @@ -1,7 +1,7 @@ From ba453a89148ea2289e71741225273a02ae2db768 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:49:56 +0200 -Subject: [PATCH 03/11] buttons +Subject: [PATCH 03/12] buttons --- drivers/input/misc/soc_button_array.c | 145 ++++++++++++++++++++-- diff --git a/patches/4.19/0004-cameras.patch b/patches/4.19/0004-cameras.patch index 80abd64d5..01491cb69 100644 --- a/patches/4.19/0004-cameras.patch +++ b/patches/4.19/0004-cameras.patch @@ -1,7 +1,7 @@ From 4f79924d2848c13e9a0830c0c575421768f8d58a Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:50:29 +0200 -Subject: [PATCH 04/11] cameras +Subject: [PATCH 04/12] cameras --- drivers/media/usb/uvc/uvc_driver.c | 40 + diff --git a/patches/4.19/0005-ipts.patch b/patches/4.19/0005-ipts.patch index 4d1332568..491d232a6 100644 --- a/patches/4.19/0005-ipts.patch +++ b/patches/4.19/0005-ipts.patch @@ -1,7 +1,7 @@ From aa2ce90ff8ee8ad90a5e84004b748e709167bd0f Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:50:47 +0200 -Subject: [PATCH 05/11] ipts +Subject: [PATCH 05/12] ipts --- drivers/gpu/drm/i915/Makefile | 3 + diff --git a/patches/4.19/0006-hid.patch b/patches/4.19/0006-hid.patch index 80ed27d86..86ef4f3bc 100644 --- a/patches/4.19/0006-hid.patch +++ b/patches/4.19/0006-hid.patch @@ -1,7 +1,7 @@ From 3895e7b026d525d70fdc0f4a6dd59b08c9f44022 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:51:26 +0200 -Subject: [PATCH 06/11] hid +Subject: [PATCH 06/12] hid --- drivers/hid/hid-ids.h | 21 +++++++++---- diff --git a/patches/4.19/0007-sdcard-reader.patch b/patches/4.19/0007-sdcard-reader.patch index 35b8d5938..9d5dd4bb5 100644 --- a/patches/4.19/0007-sdcard-reader.patch +++ b/patches/4.19/0007-sdcard-reader.patch @@ -1,7 +1,7 @@ From 4cbc99c208e1938349aec603aee10b202a54f54a Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:51:55 +0200 -Subject: [PATCH 07/11] sdcard-reader +Subject: [PATCH 07/12] sdcard-reader --- drivers/usb/core/hub.c | 3 ++- diff --git a/patches/4.19/0008-wifi.patch b/patches/4.19/0008-wifi.patch index b91c63423..4d0be2c5b 100644 --- a/patches/4.19/0008-wifi.patch +++ b/patches/4.19/0008-wifi.patch @@ -1,7 +1,7 @@ From 52cb41ede0999511587b9a2523771238c12f8033 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:52:12 +0200 -Subject: [PATCH 08/11] wifi +Subject: [PATCH 08/12] wifi --- drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 3 +-- diff --git a/patches/4.19/0009-surface3-power.patch b/patches/4.19/0009-surface3-power.patch index a40889389..086701247 100644 --- a/patches/4.19/0009-surface3-power.patch +++ b/patches/4.19/0009-surface3-power.patch @@ -1,7 +1,7 @@ From 09ddddeb396321184eb2591c20e681d48623c34d Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:52:29 +0200 -Subject: [PATCH 09/11] surface3-power +Subject: [PATCH 09/12] surface3-power --- drivers/platform/x86/Kconfig | 7 + diff --git a/patches/4.19/0010-mwlwifi.patch b/patches/4.19/0010-mwlwifi.patch index 753cbb06e..6219ae68b 100644 --- a/patches/4.19/0010-mwlwifi.patch +++ b/patches/4.19/0010-mwlwifi.patch @@ -1,7 +1,7 @@ From d27de602a55f146e79c125287e6dbc3aa70ded38 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:52:52 +0200 -Subject: [PATCH 10/11] mwlwifi +Subject: [PATCH 10/12] mwlwifi --- drivers/net/wireless/marvell/Kconfig | 1 + diff --git a/patches/4.19/0011-surface-lte.patch b/patches/4.19/0011-surface-lte.patch index 0d5102daa..7885116ec 100644 --- a/patches/4.19/0011-surface-lte.patch +++ b/patches/4.19/0011-surface-lte.patch @@ -1,7 +1,7 @@ From 4b31faa2ddaffa6e6963c54ff6574178de94918e Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 2 Jul 2019 23:53:15 +0200 -Subject: [PATCH 11/11] surface-lte +Subject: [PATCH 11/12] surface-lte --- drivers/usb/serial/qcserial.c | 1 + diff --git a/patches/4.19/0012-surfacebook2-dgpu.patch b/patches/4.19/0012-surfacebook2-dgpu.patch new file mode 100644 index 000000000..3a8c6e853 --- /dev/null +++ b/patches/4.19/0012-surfacebook2-dgpu.patch @@ -0,0 +1,359 @@ +From c7eb71b21227f0ee6b46a13c9b4f9df49dd23979 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Tue, 2 Jul 2019 23:58:22 +0200 +Subject: [PATCH 12/12] surfacebook2-dgpu + +--- + drivers/platform/x86/Kconfig | 9 + + drivers/platform/x86/Makefile | 1 + + drivers/platform/x86/surfacebook2_dgpu_hps.c | 306 +++++++++++++++++++ + 3 files changed, 316 insertions(+) + create mode 100644 drivers/platform/x86/surfacebook2_dgpu_hps.c + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index d6695d8fc795..16f40109337c 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -436,6 +436,15 @@ config SURFACE3_WMI + To compile this driver as a module, choose M here: the module will + be called surface3-wmi. + ++config SURFACE_BOOK2_DGPU_HPS ++ tristate "Surface Book 2 dGPU Hot-Plug System Driver" ++ depends on ACPI ++ ---help--- ++ This is an experimetnal driver to control the power-state of the ++ Surface Book 2 dGPU. ++ ++ If you have a Surface Book 2, say Y or M here. ++ + config THINKPAD_ACPI + tristate "ThinkPad ACPI Laptop Extras" + depends on ACPI +diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile +index dd045ccf3a90..6d24ede71496 100644 +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -45,6 +45,7 @@ obj-$(CONFIG_ACPI_WMI) += wmi.o + obj-$(CONFIG_MSI_WMI) += msi-wmi.o + obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o + obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o ++obj-$(CONFIG_SURFACE_BOOK2_DGPU_HPS) += surfacebook2_dgpu_hps.o + obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o + obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o + obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o +diff --git a/drivers/platform/x86/surfacebook2_dgpu_hps.c b/drivers/platform/x86/surfacebook2_dgpu_hps.c +new file mode 100644 +index 000000000000..7639fb0029d8 +--- /dev/null ++++ b/drivers/platform/x86/surfacebook2_dgpu_hps.c +@@ -0,0 +1,306 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++ ++#define SB2_SHPS_DSM_REVISION 1 ++#define SB2_SHPS_DSM_GPU_STATE 0x05 ++ ++static const guid_t SB2_SHPS_DSM_UUID = ++ GUID_INIT(0x5515a847, 0xed55, 0x4b27, 0x83, 0x52, 0xcd, ++ 0x32, 0x0e, 0x10, 0x36, 0x0a); ++ ++#define SB2_PARAM_PERM (S_IRUGO | S_IWUSR) ++ ++ ++static const struct acpi_gpio_params gpio_base_presence_int = { 0, 0, false }; ++static const struct acpi_gpio_params gpio_base_presence = { 1, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_power_int = { 2, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_power = { 3, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_presence_int = { 4, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_presence = { 5, 0, false }; ++ ++static const struct acpi_gpio_mapping sb2_mshw0153_acpi_gpios[] = { ++ { "base_presence-int-gpio", &gpio_base_presence_int, 1 }, ++ { "base_presence-gpio", &gpio_base_presence, 1 }, ++ { "dgpu_power-int-gpio", &gpio_dgpu_power_int, 1 }, ++ { "dgpu_power-gpio", &gpio_dgpu_power, 1 }, ++ { "dgpu_presence-int-gpio", &gpio_dgpu_presence_int, 1 }, ++ { "dgpu_presence-gpio", &gpio_dgpu_presence, 1 }, ++ { }, ++}; ++ ++ ++enum sb2_dgpu_power { ++ SB2_DGPU_POWER_OFF = 0, ++ SB2_DGPU_POWER_ON = 1, ++ ++ __SB2_DGPU_POWER__START = 0, ++ __SB2_DGPU_POWER__END = 1, ++}; ++ ++enum sb2_param_dgpu_power { ++ SB2_PARAM_DGPU_POWER_OFF = SB2_DGPU_POWER_OFF, ++ SB2_PARAM_DGPU_POWER_ON = SB2_DGPU_POWER_ON, ++ SB2_PARAM_DGPU_POWER_AS_IS = 2, ++ ++ __SB2_PARAM_DGPU_POWER__START = 0, ++ __SB2_PARAM_DGPU_POWER__END = 2, ++}; ++ ++static const char* sb2_dgpu_power_str(enum sb2_dgpu_power power) { ++ if (power == SB2_DGPU_POWER_OFF) { ++ return "off"; ++ } else if (power == SB2_DGPU_POWER_ON) { ++ return "on"; ++ } else { ++ return ""; ++ } ++} ++ ++ ++struct sb2_shps_driver_data { ++ struct mutex dgpu_power_lock; ++ enum sb2_dgpu_power dgpu_power; ++}; ++ ++ ++static int __sb2_shps_dgpu_set_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ acpi_handle handle = ACPI_HANDLE(&pdev->dev); ++ union acpi_object *result; ++ union acpi_object param; ++ ++ param.type = ACPI_TYPE_INTEGER; ++ param.integer.value = power == SB2_DGPU_POWER_ON; ++ ++ result = acpi_evaluate_dsm_typed(handle, &SB2_SHPS_DSM_UUID, SB2_SHPS_DSM_REVISION, ++ SB2_SHPS_DSM_GPU_STATE, ¶m, ACPI_TYPE_BUFFER); ++ ++ if (IS_ERR_OR_NULL(result)) { ++ return result ? PTR_ERR(result) : -EFAULT; ++ } ++ ++ if (result->buffer.length != 1 || result->buffer.pointer[0] != 0) { ++ return -EIO; ++ } ++ ++ drvdata->dgpu_power = power; ++ ++ printk(KERN_INFO "sb2_shps: dGPU power state set to \'%s\'\n", sb2_dgpu_power_str(power)); ++ ++ ACPI_FREE(result); ++ return 0; ++} ++ ++static int sb2_shps_dgpu_set_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ int status = 0; ++ ++ if (power < __SB2_DGPU_POWER__START || power > __SB2_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ mutex_lock(&drvdata->dgpu_power_lock); ++ if (power != drvdata->dgpu_power) { ++ status = __sb2_shps_dgpu_set_power(pdev, power); ++ } ++ mutex_unlock(&drvdata->dgpu_power_lock); ++ ++ return status; ++} ++ ++static int sb2_shps_dgpu_force_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ int status; ++ ++ if (power < __SB2_DGPU_POWER__START || power > __SB2_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ mutex_lock(&drvdata->dgpu_power_lock); ++ status = __sb2_shps_dgpu_set_power(pdev, power); ++ mutex_unlock(&drvdata->dgpu_power_lock); ++ ++ return status; ++} ++ ++ ++static int param_dgpu_power_set(const char *val, const struct kernel_param *kp) ++{ ++ int power = SB2_PARAM_DGPU_POWER_OFF; ++ int status; ++ ++ status = kstrtoint(val, 0, &power); ++ if (status) { ++ return status; ++ } ++ ++ if (power < __SB2_PARAM_DGPU_POWER__START || power > __SB2_PARAM_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ return param_set_int(val, kp); ++} ++ ++static const struct kernel_param_ops param_dgpu_power_ops = { ++ .set = param_dgpu_power_set, ++ .get = param_get_int, ++}; ++ ++static int param_dgpu_power_init = SB2_PARAM_DGPU_POWER_OFF; ++static int param_dgpu_power_exit = SB2_PARAM_DGPU_POWER_OFF; ++ ++module_param_cb(dgpu_power_init, ¶m_dgpu_power_ops, ¶m_dgpu_power_init, SB2_PARAM_PERM); ++module_param_cb(dgpu_power_exit, ¶m_dgpu_power_ops, ¶m_dgpu_power_exit, SB2_PARAM_PERM); ++ ++MODULE_PARM_DESC(dgpu_power_init, "dGPU power state to be set on init (0: off / 1: on / 2: as-is)"); ++MODULE_PARM_DESC(dgpu_power_exit, "dGPU power state to be set on exit (0: off / 1: on / 2: as-is)"); ++ ++ ++static ssize_t dgpu_power_show(struct device *dev, struct device_attribute *attr, char *data) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ ++ return sprintf(data, "%s\n", sb2_dgpu_power_str(drvdata->dgpu_power)); ++} ++ ++static ssize_t dgpu_power_store(struct device *dev, struct device_attribute *attr, ++ const char *data, size_t count) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ bool power = false; ++ int status; ++ ++ status = kstrtobool(data, &power); ++ if (status) { ++ return status; ++ } ++ ++ if (power) { ++ status = sb2_shps_dgpu_set_power(pdev, SB2_DGPU_POWER_ON); ++ } else { ++ status = sb2_shps_dgpu_set_power(pdev, SB2_DGPU_POWER_OFF); ++ } ++ ++ return status < 0 ? status : count; ++} ++ ++const static DEVICE_ATTR_RW(dgpu_power); ++ ++ ++#ifdef CONFIG_PM ++ ++static int sb2_shps_resume(struct device *dev) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ ++ return sb2_shps_dgpu_force_power(pdev, drvdata->dgpu_power); ++} ++ ++static SIMPLE_DEV_PM_OPS(sb2_shps_pm_ops, NULL, sb2_shps_resume); ++ ++#endif ++ ++ ++static int sb2_shps_probe(struct platform_device *pdev) ++{ ++ struct sb2_shps_driver_data *drvdata; ++ struct acpi_device *shps_dev = ACPI_COMPANION(&pdev->dev); ++ int status = 0; ++ ++ if (gpiod_count(&pdev->dev, NULL) < 0) { ++ return -ENODEV; ++ } ++ ++ status = acpi_dev_add_driver_gpios(shps_dev, sb2_mshw0153_acpi_gpios); ++ if (status) { ++ return status; ++ } ++ ++ drvdata = kzalloc(sizeof(struct sb2_shps_driver_data), GFP_KERNEL); ++ if (!drvdata) { ++ status = -ENOMEM; ++ goto err_alloc_drvdata; ++ } ++ ++ mutex_init(&drvdata->dgpu_power_lock); ++ drvdata->dgpu_power = SB2_DGPU_POWER_OFF; ++ platform_set_drvdata(pdev, drvdata); ++ ++ if (param_dgpu_power_init != SB2_PARAM_DGPU_POWER_AS_IS) { ++ status = sb2_shps_dgpu_force_power(pdev, param_dgpu_power_init); ++ if (status) { ++ goto err_set_power; ++ } ++ } ++ ++ status = sysfs_create_file(&pdev->dev.kobj, &dev_attr_dgpu_power.attr); ++ if (status) { ++ goto err_sysfs; ++ } ++ ++ return 0; ++ ++err_sysfs: ++ sb2_shps_dgpu_force_power(pdev, SB2_DGPU_POWER_OFF); ++err_set_power: ++ platform_set_drvdata(pdev, NULL); ++ kfree(drvdata); ++err_alloc_drvdata: ++ acpi_dev_remove_driver_gpios(shps_dev); ++ return status; ++} ++ ++static int sb2_shps_remove(struct platform_device *pdev) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ struct acpi_device *shps_dev = ACPI_COMPANION(&pdev->dev); ++ ++ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_dgpu_power.attr); ++ ++ if (param_dgpu_power_exit != SB2_PARAM_DGPU_POWER_AS_IS) { ++ sb2_shps_dgpu_set_power(pdev, param_dgpu_power_exit); ++ } ++ acpi_dev_remove_driver_gpios(shps_dev); ++ ++ platform_set_drvdata(pdev, NULL); ++ kfree(drvdata); ++ ++ return 0; ++} ++ ++ ++static const struct acpi_device_id sb2_shps_acpi_match[] = { ++ { "MSHW0153", 0 }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(acpi, sb2_shps_acpi_match); ++ ++static struct platform_driver sb2_shps_driver = { ++ .probe = sb2_shps_probe, ++ .remove = sb2_shps_remove, ++ .driver = { ++ .name = "sb2_shps", ++ .acpi_match_table = ACPI_PTR(sb2_shps_acpi_match), ++#ifdef CONFIG_PM ++ .pm = &sb2_shps_pm_ops, ++#endif ++ }, ++}; ++module_platform_driver(sb2_shps_driver); ++ ++MODULE_AUTHOR("Maximilian Luz "); ++MODULE_DESCRIPTION("Surface Book 2 Hot-Plug System Driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.22.0 + diff --git a/patches/5.1/0001-surface-acpi.patch b/patches/5.1/0001-surface-acpi.patch index ac7529c82..908999f32 100644 --- a/patches/5.1/0001-surface-acpi.patch +++ b/patches/5.1/0001-surface-acpi.patch @@ -1,7 +1,7 @@ From d4d2fa3647f86b84ed6d38c8180cb020eb88627d Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:22:49 +0200 -Subject: [PATCH 01/11] surface-acpi +Subject: [PATCH 01/12] surface-acpi --- drivers/acpi/acpica/dsopcode.c | 2 +- diff --git a/patches/5.1/0002-suspend.patch b/patches/5.1/0002-suspend.patch index 8fc736b80..6bf0f910e 100644 --- a/patches/5.1/0002-suspend.patch +++ b/patches/5.1/0002-suspend.patch @@ -1,7 +1,7 @@ From c2ae9c80d630190f67b102303f794277cd916d9f Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:24:31 +0200 -Subject: [PATCH 02/11] suspend +Subject: [PATCH 02/12] suspend --- drivers/nvme/host/nvme.h | 5 +++++ diff --git a/patches/5.1/0003-buttons.patch b/patches/5.1/0003-buttons.patch index 7c4c28374..0c630de2a 100644 --- a/patches/5.1/0003-buttons.patch +++ b/patches/5.1/0003-buttons.patch @@ -1,7 +1,7 @@ From 8b583fd83792f28f23461186b0c44d9c1554204e Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:25:27 +0200 -Subject: [PATCH 03/11] buttons +Subject: [PATCH 03/12] buttons --- drivers/input/misc/soc_button_array.c | 145 ++++++++++++++++++++-- diff --git a/patches/5.1/0004-cameras.patch b/patches/5.1/0004-cameras.patch index 625f5cd50..0cfb222d9 100644 --- a/patches/5.1/0004-cameras.patch +++ b/patches/5.1/0004-cameras.patch @@ -1,7 +1,7 @@ From ee99ccaced33d4db9d807b5452507c2b4257f595 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:27:27 +0200 -Subject: [PATCH 04/11] cameras +Subject: [PATCH 04/12] cameras --- drivers/media/usb/uvc/uvc_driver.c | 40 + diff --git a/patches/5.1/0005-ipts.patch b/patches/5.1/0005-ipts.patch index 7e66e90de..1c401ebdb 100644 --- a/patches/5.1/0005-ipts.patch +++ b/patches/5.1/0005-ipts.patch @@ -1,7 +1,7 @@ From fa6be7e31d29959edc738986507fed1e1a877e2e Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:28:10 +0200 -Subject: [PATCH 05/11] ipts +Subject: [PATCH 05/12] ipts --- drivers/gpu/drm/i915/Makefile | 3 + diff --git a/patches/5.1/0006-hid.patch b/patches/5.1/0006-hid.patch index d0128d44a..5bf5ca7e3 100644 --- a/patches/5.1/0006-hid.patch +++ b/patches/5.1/0006-hid.patch @@ -1,7 +1,7 @@ From d784fa6928c75c033a240d6db839c3aacd9edd33 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:28:41 +0200 -Subject: [PATCH 06/11] hid +Subject: [PATCH 06/12] hid --- drivers/hid/hid-ids.h | 21 +++++++++---- diff --git a/patches/5.1/0007-sdcard-reader.patch b/patches/5.1/0007-sdcard-reader.patch index a0bbba873..fbb84ae2c 100644 --- a/patches/5.1/0007-sdcard-reader.patch +++ b/patches/5.1/0007-sdcard-reader.patch @@ -1,7 +1,7 @@ From 1b434e8d2943d1c6a3fb9eb7936f8ecc5c1551e3 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:29:19 +0200 -Subject: [PATCH 07/11] sdcard-reader +Subject: [PATCH 07/12] sdcard-reader --- drivers/usb/core/hub.c | 3 ++- diff --git a/patches/5.1/0008-wifi.patch b/patches/5.1/0008-wifi.patch index 5a7b53662..20bd5fa35 100644 --- a/patches/5.1/0008-wifi.patch +++ b/patches/5.1/0008-wifi.patch @@ -1,7 +1,7 @@ From 8f2bb111745b57988030776899049153dadf2e3d Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:30:18 +0200 -Subject: [PATCH 08/11] wifi +Subject: [PATCH 08/12] wifi --- drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 3 +-- diff --git a/patches/5.1/0009-surface3-power.patch b/patches/5.1/0009-surface3-power.patch index aad68b841..6a0d6cfe0 100644 --- a/patches/5.1/0009-surface3-power.patch +++ b/patches/5.1/0009-surface3-power.patch @@ -1,7 +1,7 @@ From facb57708454c1424e5dffe2be999356fc88984a Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:30:44 +0200 -Subject: [PATCH 09/11] surface3-power +Subject: [PATCH 09/12] surface3-power --- drivers/platform/x86/Kconfig | 7 + diff --git a/patches/5.1/0010-mwlwifi.patch b/patches/5.1/0010-mwlwifi.patch index d413e05af..5441b9161 100644 --- a/patches/5.1/0010-mwlwifi.patch +++ b/patches/5.1/0010-mwlwifi.patch @@ -1,7 +1,7 @@ From 74d3a35c573f41861590ee786400067220c300b6 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:31:18 +0200 -Subject: [PATCH 10/11] mwlwifi +Subject: [PATCH 10/12] mwlwifi --- drivers/net/wireless/marvell/Kconfig | 1 + diff --git a/patches/5.1/0011-surface-lte.patch b/patches/5.1/0011-surface-lte.patch index 714656333..8c8bd09b0 100644 --- a/patches/5.1/0011-surface-lte.patch +++ b/patches/5.1/0011-surface-lte.patch @@ -1,7 +1,7 @@ From ba5ab6c097f826ef6ec92379383f8b9963b8f48c Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Wed, 3 Jul 2019 00:32:00 +0200 -Subject: [PATCH 11/11] surface-lte +Subject: [PATCH 11/12] surface-lte --- drivers/usb/serial/qcserial.c | 1 + diff --git a/patches/5.1/0012-surfacebook2-dgpu.patch b/patches/5.1/0012-surfacebook2-dgpu.patch new file mode 100644 index 000000000..f9b0ed7c8 --- /dev/null +++ b/patches/5.1/0012-surfacebook2-dgpu.patch @@ -0,0 +1,359 @@ +From 42b801e957cc7aa47e7d6a869970c149d959b539 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Wed, 3 Jul 2019 00:35:24 +0200 +Subject: [PATCH 12/12] surfacebook2-dgpu + +--- + drivers/platform/x86/Kconfig | 9 + + drivers/platform/x86/Makefile | 1 + + drivers/platform/x86/surfacebook2_dgpu_hps.c | 306 +++++++++++++++++++ + 3 files changed, 316 insertions(+) + create mode 100644 drivers/platform/x86/surfacebook2_dgpu_hps.c + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 21ffc03cd372..200d4d55da98 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -483,6 +483,15 @@ config SURFACE3_WMI + To compile this driver as a module, choose M here: the module will + be called surface3-wmi. + ++config SURFACE_BOOK2_DGPU_HPS ++ tristate "Surface Book 2 dGPU Hot-Plug System Driver" ++ depends on ACPI ++ ---help--- ++ This is an experimetnal driver to control the power-state of the ++ Surface Book 2 dGPU. ++ ++ If you have a Surface Book 2, say Y or M here. ++ + config THINKPAD_ACPI + tristate "ThinkPad ACPI Laptop Extras" + depends on ACPI +diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile +index 278ce32df99f..0faf98020b84 100644 +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -49,6 +49,7 @@ obj-$(CONFIG_ACPI_WMI) += wmi.o + obj-$(CONFIG_MSI_WMI) += msi-wmi.o + obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o + obj-$(CONFIG_SURFACE3_WMI) += surface3-wmi.o ++obj-$(CONFIG_SURFACE_BOOK2_DGPU_HPS) += surfacebook2_dgpu_hps.o + obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o + obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o + obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o +diff --git a/drivers/platform/x86/surfacebook2_dgpu_hps.c b/drivers/platform/x86/surfacebook2_dgpu_hps.c +new file mode 100644 +index 000000000000..7639fb0029d8 +--- /dev/null ++++ b/drivers/platform/x86/surfacebook2_dgpu_hps.c +@@ -0,0 +1,306 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++ ++#define SB2_SHPS_DSM_REVISION 1 ++#define SB2_SHPS_DSM_GPU_STATE 0x05 ++ ++static const guid_t SB2_SHPS_DSM_UUID = ++ GUID_INIT(0x5515a847, 0xed55, 0x4b27, 0x83, 0x52, 0xcd, ++ 0x32, 0x0e, 0x10, 0x36, 0x0a); ++ ++#define SB2_PARAM_PERM (S_IRUGO | S_IWUSR) ++ ++ ++static const struct acpi_gpio_params gpio_base_presence_int = { 0, 0, false }; ++static const struct acpi_gpio_params gpio_base_presence = { 1, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_power_int = { 2, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_power = { 3, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_presence_int = { 4, 0, false }; ++static const struct acpi_gpio_params gpio_dgpu_presence = { 5, 0, false }; ++ ++static const struct acpi_gpio_mapping sb2_mshw0153_acpi_gpios[] = { ++ { "base_presence-int-gpio", &gpio_base_presence_int, 1 }, ++ { "base_presence-gpio", &gpio_base_presence, 1 }, ++ { "dgpu_power-int-gpio", &gpio_dgpu_power_int, 1 }, ++ { "dgpu_power-gpio", &gpio_dgpu_power, 1 }, ++ { "dgpu_presence-int-gpio", &gpio_dgpu_presence_int, 1 }, ++ { "dgpu_presence-gpio", &gpio_dgpu_presence, 1 }, ++ { }, ++}; ++ ++ ++enum sb2_dgpu_power { ++ SB2_DGPU_POWER_OFF = 0, ++ SB2_DGPU_POWER_ON = 1, ++ ++ __SB2_DGPU_POWER__START = 0, ++ __SB2_DGPU_POWER__END = 1, ++}; ++ ++enum sb2_param_dgpu_power { ++ SB2_PARAM_DGPU_POWER_OFF = SB2_DGPU_POWER_OFF, ++ SB2_PARAM_DGPU_POWER_ON = SB2_DGPU_POWER_ON, ++ SB2_PARAM_DGPU_POWER_AS_IS = 2, ++ ++ __SB2_PARAM_DGPU_POWER__START = 0, ++ __SB2_PARAM_DGPU_POWER__END = 2, ++}; ++ ++static const char* sb2_dgpu_power_str(enum sb2_dgpu_power power) { ++ if (power == SB2_DGPU_POWER_OFF) { ++ return "off"; ++ } else if (power == SB2_DGPU_POWER_ON) { ++ return "on"; ++ } else { ++ return ""; ++ } ++} ++ ++ ++struct sb2_shps_driver_data { ++ struct mutex dgpu_power_lock; ++ enum sb2_dgpu_power dgpu_power; ++}; ++ ++ ++static int __sb2_shps_dgpu_set_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ acpi_handle handle = ACPI_HANDLE(&pdev->dev); ++ union acpi_object *result; ++ union acpi_object param; ++ ++ param.type = ACPI_TYPE_INTEGER; ++ param.integer.value = power == SB2_DGPU_POWER_ON; ++ ++ result = acpi_evaluate_dsm_typed(handle, &SB2_SHPS_DSM_UUID, SB2_SHPS_DSM_REVISION, ++ SB2_SHPS_DSM_GPU_STATE, ¶m, ACPI_TYPE_BUFFER); ++ ++ if (IS_ERR_OR_NULL(result)) { ++ return result ? PTR_ERR(result) : -EFAULT; ++ } ++ ++ if (result->buffer.length != 1 || result->buffer.pointer[0] != 0) { ++ return -EIO; ++ } ++ ++ drvdata->dgpu_power = power; ++ ++ printk(KERN_INFO "sb2_shps: dGPU power state set to \'%s\'\n", sb2_dgpu_power_str(power)); ++ ++ ACPI_FREE(result); ++ return 0; ++} ++ ++static int sb2_shps_dgpu_set_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ int status = 0; ++ ++ if (power < __SB2_DGPU_POWER__START || power > __SB2_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ mutex_lock(&drvdata->dgpu_power_lock); ++ if (power != drvdata->dgpu_power) { ++ status = __sb2_shps_dgpu_set_power(pdev, power); ++ } ++ mutex_unlock(&drvdata->dgpu_power_lock); ++ ++ return status; ++} ++ ++static int sb2_shps_dgpu_force_power(struct platform_device *pdev, enum sb2_dgpu_power power) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ int status; ++ ++ if (power < __SB2_DGPU_POWER__START || power > __SB2_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ mutex_lock(&drvdata->dgpu_power_lock); ++ status = __sb2_shps_dgpu_set_power(pdev, power); ++ mutex_unlock(&drvdata->dgpu_power_lock); ++ ++ return status; ++} ++ ++ ++static int param_dgpu_power_set(const char *val, const struct kernel_param *kp) ++{ ++ int power = SB2_PARAM_DGPU_POWER_OFF; ++ int status; ++ ++ status = kstrtoint(val, 0, &power); ++ if (status) { ++ return status; ++ } ++ ++ if (power < __SB2_PARAM_DGPU_POWER__START || power > __SB2_PARAM_DGPU_POWER__END) { ++ return -EINVAL; ++ } ++ ++ return param_set_int(val, kp); ++} ++ ++static const struct kernel_param_ops param_dgpu_power_ops = { ++ .set = param_dgpu_power_set, ++ .get = param_get_int, ++}; ++ ++static int param_dgpu_power_init = SB2_PARAM_DGPU_POWER_OFF; ++static int param_dgpu_power_exit = SB2_PARAM_DGPU_POWER_OFF; ++ ++module_param_cb(dgpu_power_init, ¶m_dgpu_power_ops, ¶m_dgpu_power_init, SB2_PARAM_PERM); ++module_param_cb(dgpu_power_exit, ¶m_dgpu_power_ops, ¶m_dgpu_power_exit, SB2_PARAM_PERM); ++ ++MODULE_PARM_DESC(dgpu_power_init, "dGPU power state to be set on init (0: off / 1: on / 2: as-is)"); ++MODULE_PARM_DESC(dgpu_power_exit, "dGPU power state to be set on exit (0: off / 1: on / 2: as-is)"); ++ ++ ++static ssize_t dgpu_power_show(struct device *dev, struct device_attribute *attr, char *data) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ ++ return sprintf(data, "%s\n", sb2_dgpu_power_str(drvdata->dgpu_power)); ++} ++ ++static ssize_t dgpu_power_store(struct device *dev, struct device_attribute *attr, ++ const char *data, size_t count) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ bool power = false; ++ int status; ++ ++ status = kstrtobool(data, &power); ++ if (status) { ++ return status; ++ } ++ ++ if (power) { ++ status = sb2_shps_dgpu_set_power(pdev, SB2_DGPU_POWER_ON); ++ } else { ++ status = sb2_shps_dgpu_set_power(pdev, SB2_DGPU_POWER_OFF); ++ } ++ ++ return status < 0 ? status : count; ++} ++ ++const static DEVICE_ATTR_RW(dgpu_power); ++ ++ ++#ifdef CONFIG_PM ++ ++static int sb2_shps_resume(struct device *dev) ++{ ++ struct platform_device *pdev = container_of(dev, struct platform_device, dev); ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ ++ return sb2_shps_dgpu_force_power(pdev, drvdata->dgpu_power); ++} ++ ++static SIMPLE_DEV_PM_OPS(sb2_shps_pm_ops, NULL, sb2_shps_resume); ++ ++#endif ++ ++ ++static int sb2_shps_probe(struct platform_device *pdev) ++{ ++ struct sb2_shps_driver_data *drvdata; ++ struct acpi_device *shps_dev = ACPI_COMPANION(&pdev->dev); ++ int status = 0; ++ ++ if (gpiod_count(&pdev->dev, NULL) < 0) { ++ return -ENODEV; ++ } ++ ++ status = acpi_dev_add_driver_gpios(shps_dev, sb2_mshw0153_acpi_gpios); ++ if (status) { ++ return status; ++ } ++ ++ drvdata = kzalloc(sizeof(struct sb2_shps_driver_data), GFP_KERNEL); ++ if (!drvdata) { ++ status = -ENOMEM; ++ goto err_alloc_drvdata; ++ } ++ ++ mutex_init(&drvdata->dgpu_power_lock); ++ drvdata->dgpu_power = SB2_DGPU_POWER_OFF; ++ platform_set_drvdata(pdev, drvdata); ++ ++ if (param_dgpu_power_init != SB2_PARAM_DGPU_POWER_AS_IS) { ++ status = sb2_shps_dgpu_force_power(pdev, param_dgpu_power_init); ++ if (status) { ++ goto err_set_power; ++ } ++ } ++ ++ status = sysfs_create_file(&pdev->dev.kobj, &dev_attr_dgpu_power.attr); ++ if (status) { ++ goto err_sysfs; ++ } ++ ++ return 0; ++ ++err_sysfs: ++ sb2_shps_dgpu_force_power(pdev, SB2_DGPU_POWER_OFF); ++err_set_power: ++ platform_set_drvdata(pdev, NULL); ++ kfree(drvdata); ++err_alloc_drvdata: ++ acpi_dev_remove_driver_gpios(shps_dev); ++ return status; ++} ++ ++static int sb2_shps_remove(struct platform_device *pdev) ++{ ++ struct sb2_shps_driver_data *drvdata = platform_get_drvdata(pdev); ++ struct acpi_device *shps_dev = ACPI_COMPANION(&pdev->dev); ++ ++ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_dgpu_power.attr); ++ ++ if (param_dgpu_power_exit != SB2_PARAM_DGPU_POWER_AS_IS) { ++ sb2_shps_dgpu_set_power(pdev, param_dgpu_power_exit); ++ } ++ acpi_dev_remove_driver_gpios(shps_dev); ++ ++ platform_set_drvdata(pdev, NULL); ++ kfree(drvdata); ++ ++ return 0; ++} ++ ++ ++static const struct acpi_device_id sb2_shps_acpi_match[] = { ++ { "MSHW0153", 0 }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(acpi, sb2_shps_acpi_match); ++ ++static struct platform_driver sb2_shps_driver = { ++ .probe = sb2_shps_probe, ++ .remove = sb2_shps_remove, ++ .driver = { ++ .name = "sb2_shps", ++ .acpi_match_table = ACPI_PTR(sb2_shps_acpi_match), ++#ifdef CONFIG_PM ++ .pm = &sb2_shps_pm_ops, ++#endif ++ }, ++}; ++module_platform_driver(sb2_shps_driver); ++ ++MODULE_AUTHOR("Maximilian Luz "); ++MODULE_DESCRIPTION("Surface Book 2 Hot-Plug System Driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.22.0 +