This commit is contained in:
Kevin Baensch 2019-02-28 08:42:46 +01:00
commit 9ec0e2e071
19 changed files with 42920 additions and 0 deletions

79
linux_surface/default.nix Normal file
View file

@ -0,0 +1,79 @@
{ stdenv, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
with stdenv.lib;
buildLinux (args // rec {
version = "4.19.25";
# modDirVersion needs to be x.y.z, will automatically add .0 if needed
modDirVersion = if (modDirVersionArg == null) then concatStrings (intersperse "." (take 3 (splitString "." "${version}.0"))) else modDirVersionArg;
# branchVersion needs to be x.y
extraMeta.branch = concatStrings (intersperse "." (take 2 (splitString "." version)));
src = fetchurl {
url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
sha256 = "0ccpj57pv2rw78a4j5mg9sz7a37k0sn5glbn2rs6yvp9ss81vivy";
};
kernelPatches = [
{
name = "modinst-arg-list-too-long";
patch = ./patches/modinst-arg-list-too-long.patch;
}
{
name = "bridge-stp-helper";
patch = ./patches/bridge-stp-helper.patch;
}
{
name = "surface-acpi";
patch = ./patches/0001-surface-acpi.patch;
}
{
name = "resume-delay";
patch = ./patches/0002-resume-delay.patch;
}
{
name = "buttons";
patch = ./patches/0003-buttons.patch;
}
{
name = "cameras";
patch = ./patches/0004-cameras.patch;
}
{
name = "ipts";
patch = ./patches/0005-ipts.patch;
}
{
name = "hid";
patch = ./patches/0006-hid.patch;
}
{
name = "sdcard-reader";
patch = ./patches/0007-sdcard-reader.patch;
}
{
name = "wifi";
patch = ./patches/0008-wifi.patch;
}
{
name = "surface3-power";
patch = ./patches/0009-surface3-power.patch;
}
{
name = "surface-dock";
patch = ./patches/0010-surface-dock.patch;
}
{
name = "mwlwifi";
patch = ./patches/0011-mwlwifi.patch;
}
];
extraConfig = ''
I2C_DESIGNWARE_PLATFORM m
X86_INTEL_LPSS y
''
+ (args.extraConfig or "");
} // (args.argsOverride or {}))

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
From 2c96c2eabfe092f7b1ada3827737009ee84cb60f Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:45:42 -0500
Subject: [PATCH 02/11] resume-delay
---
kernel/power/suspend.c | 11 +++++++++++
kernel/sysctl.c | 9 +++++++++
2 files changed, 20 insertions(+)
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 0bd595a0b610..a8385e8894a5 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -526,6 +526,8 @@ int suspend_devices_and_enter(suspend_state_t state)
goto Resume_devices;
}
+unsigned int resume_delay = 3000;
+
/**
* suspend_finish - Clean up before finishing the suspend sequence.
*
@@ -534,6 +536,15 @@ int suspend_devices_and_enter(suspend_state_t state)
*/
static void suspend_finish(void)
{
+ if (resume_delay) {
+ /* Give kernel threads a head start, such that usb-storage
+ * can detect devices before syslog attempts to write log
+ * messages from the suspend code.
+ */
+ thaw_kernel_threads();
+ pr_debug("PM: Sleeping for %d milliseconds.\n", resume_delay);
+ msleep(resume_delay);
+ }
suspend_thaw_processes();
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index cc02050fd0c4..11802bda1a5d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -311,7 +311,16 @@ static int min_extfrag_threshold;
static int max_extfrag_threshold = 1000;
#endif
+extern unsigned int resume_delay;
+
static struct ctl_table kern_table[] = {
+ {
+ .procname = "resume_delay",
+ .data = &resume_delay,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
{
.procname = "sched_child_runs_first",
.data = &sysctl_sched_child_runs_first,
--
2.17.1

View file

@ -0,0 +1,207 @@
From 8a6ddaf22fc30f97b8d47d40d610671b58158fc7 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:51:25 -0500
Subject: [PATCH 03/11] buttons
---
drivers/input/misc/soc_button_array.c | 84 +++++++++++++++++++++--
drivers/platform/x86/surfacepro3_button.c | 36 ++++++++++
2 files changed, 114 insertions(+), 6 deletions(-)
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index 23520df7650f..1ea239ff426d 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -29,12 +29,24 @@ struct soc_button_info {
bool wakeup;
};
+struct soc_device_data {
+ /* Button info, may be NULL. */
+ struct soc_button_info *button_info;
+ /* Special device check function, may be NULL. */
+ int (*check)(struct device *);
+};
+
/*
* Some of the buttons like volume up/down are auto repeat, while others
* are not. To support both, we register two platform devices, and put
* buttons into them based on whether the key should be auto repeat.
*/
-#define BUTTON_TYPES 2
+#define BUTTON_TYPES 2
+
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35);
struct soc_button_data {
struct platform_device *children[BUTTON_TYPES];
@@ -310,6 +322,7 @@ static int soc_button_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct acpi_device_id *id;
+ struct soc_device_data *device_data;
struct soc_button_info *button_info;
struct soc_button_data *priv;
struct platform_device *pd;
@@ -320,12 +333,20 @@ static int soc_button_probe(struct platform_device *pdev)
if (!id)
return -ENODEV;
- if (!id->driver_data) {
+ device_data = (struct soc_device_data *)id->driver_data;
+ if (device_data && device_data->check) {
+ // device dependent check, required for MSHW0040
+ error = device_data->check(dev);
+ if (error != 0)
+ return error;
+ }
+
+ if (device_data && device_data->button_info) {
+ button_info = (struct soc_button_info *)device_data->button_info;
+ } else {
button_info = soc_button_get_button_info(dev);
if (IS_ERR(button_info))
return PTR_ERR(button_info);
- } else {
- button_info = (struct soc_button_info *)id->driver_data;
}
error = gpiod_count(dev, NULL);
@@ -357,7 +378,7 @@ static int soc_button_probe(struct platform_device *pdev)
if (!priv->children[0] && !priv->children[1])
return -ENODEV;
- if (!id->driver_data)
+ if (!device_data || !device_data->button_info)
devm_kfree(dev, button_info);
return 0;
@@ -377,9 +398,60 @@ static struct soc_button_info soc_button_PNP0C40[] = {
{ }
};
+static struct soc_device_data soc_device_PNP0C40 = {
+ .button_info = soc_button_PNP0C40,
+ .check = NULL,
+};
+
+/*
+ * Special device check for Surface Book 2 and Surface Pro (2017).
+ * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned
+ * devices use MSHW0040 for power and volume buttons, however the way they
+ * have to be addressed differs. Make sure that we only load this drivers
+ * for the correct devices by checking the OEM Platform Revision provided by
+ * the _DSM method.
+ */
+static int soc_device_check_MSHW0040(struct device *dev)
+{
+ acpi_handle handle = ACPI_HANDLE(dev);
+ union acpi_object *result;
+ u64 oem_platform_rev = 0;
+
+ // get OEM board revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER);
+
+ if (result) {
+ oem_platform_rev = result->integer.value;
+ ACPI_FREE(result);
+ }
+
+ dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+
+ return oem_platform_rev > 0 ? 0 : -ENODEV;
+}
+
+/*
+ * Button infos for Microsoft Surface Book 2 and Surface Pro (2017).
+ * Extracted from DSDT.
+ */
+static struct soc_button_info soc_button_MSHW0040[] = {
+ { "power", 0, EV_KEY, KEY_POWER, false, true },
+ { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false },
+ { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false },
+ { }
+};
+
+static struct soc_device_data soc_device_MSHW0040 = {
+ .button_info = soc_button_MSHW0040,
+ .check = soc_device_check_MSHW0040,
+};
+
static const struct acpi_device_id soc_button_acpi_match[] = {
- { "PNP0C40", (unsigned long)soc_button_PNP0C40 },
+ { "PNP0C40", (unsigned long)&soc_device_PNP0C40 },
{ "ACPI0011", 0 },
+ /* Microsoft Surface Book 2 and Surface Pro (2017) */
+ { "MSHW0040", (unsigned long)&soc_device_MSHW0040 },
{ }
};
diff --git a/drivers/platform/x86/surfacepro3_button.c b/drivers/platform/x86/surfacepro3_button.c
index 1b491690ce07..b67f559ee209 100644
--- a/drivers/platform/x86/surfacepro3_button.c
+++ b/drivers/platform/x86/surfacepro3_button.c
@@ -24,6 +24,12 @@
#define SURFACE_BUTTON_OBJ_NAME "VGBI"
#define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
+#define MSHW0040_DSM_REVISION 0x01
+#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
+static const guid_t MSHW0040_DSM_UUID =
+ GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35);
+
+
#define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
#define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
@@ -146,6 +152,32 @@ static int surface_button_resume(struct device *dev)
}
#endif
+/*
+ * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
+ * ID (MSHW0040) for the power/volume buttons. Make sure this is the right
+ * device by checking for the _DSM method and OEM Platform Revision.
+ */
+static int surface_button_check_MSHW0040(struct acpi_device *dev)
+{
+ acpi_handle handle = dev->handle;
+ union acpi_object *result;
+ u64 oem_platform_rev = 0;
+
+ // get OEM board revision
+ result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, MSHW0040_DSM_REVISION,
+ MSHW0040_DSM_GET_OMPR, NULL, ACPI_TYPE_INTEGER);
+
+ if (result) {
+ oem_platform_rev = result->integer.value;
+ ACPI_FREE(result);
+ }
+
+ dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+
+ return oem_platform_rev == 0 ? 0 : -ENODEV;
+}
+
+
static int surface_button_add(struct acpi_device *device)
{
struct surface_button *button;
@@ -158,6 +190,10 @@ static int surface_button_add(struct acpi_device *device)
strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV;
+ error = surface_button_check_MSHW0040(device);
+ if (error)
+ return error;
+
button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
if (!button)
return -ENOMEM;
--
2.17.1

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,144 @@
From 0ba33cc0e4f65bfc9250027f810e2a78e251bb92 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:52:52 -0500
Subject: [PATCH 06/11] hid
---
drivers/hid/hid-ids.h | 20 ++++++++++----
drivers/hid/hid-microsoft.c | 3 ++-
drivers/hid/hid-multitouch.c | 52 ++++++++++++++++++++++++++++++++++++
drivers/hid/hid-quirks.c | 10 +++++++
4 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b7870e7e41d4..2ad517f1c1fe 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -800,11 +800,21 @@
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1 0x0732
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_600 0x0750
#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
-#define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
-#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
-#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
-#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
-#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+#define USB_DEVICE_ID_MS_COMFORT_KEYBOARD 0x00e3
+#define USB_DEVICE_ID_MS_SURFACE_PRO_2 0x0799
+#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
+#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
+#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 0x07dc
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1 0x07de
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4 0x07e8
+#define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1 0x07e4
+#define USB_DEVICE_ID_MS_SURFACE_BOOK 0x07cd
+#define USB_DEVICE_ID_MS_SURFACE_BOOK_2 0x0922
+#define USB_DEVICE_ID_MS_SURFACE_VHF 0xf001
+#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
#define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb
#define USB_VENDOR_ID_MOJO 0x8282
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 72d983626afd..133395b45022 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -313,7 +313,8 @@ static const struct hid_device_id ms_devices[] = {
.driver_data = MS_HIDINPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD),
.driver_data = MS_ERGONOMY},
-
+ { HID_DEVICE(BUS_VIRTUAL, 0, USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_VHF),
+ .driver_data = MS_HIDINPUT},
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B),
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 831617c386e6..1953d21398cf 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1978,6 +1978,58 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_LG,
USB_DEVICE_ID_LG_MELFAS_MT) },
+ /* Microsoft Touch Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TOUCH_COVER_2) },
+
+ /* Microsoft Type Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_2) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_3) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_4) },
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1) },
+
+ /* Microsoft Surface Book */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_BOOK) },
+
+ /* Microsoft Surface Book 2 */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_BOOK_2) },
+
+ /* Microsoft Surface Laptop */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+ USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_SURFACE_VHF) },
+
+ /* Microsoft Power Cover */
+ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+ MT_USB_DEVICE(USB_VENDOR_ID_MICROSOFT,
+ USB_DEVICE_ID_MS_POWER_COVER) },
+
/* MosArt panels */
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 77316f022c5a..2d4aafb92d85 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -111,6 +111,16 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_1), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_1), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_BOOK), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_BOOK_2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_DEVICE(BUS_VIRTUAL, 0, USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_VHF), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD), HID_QUIRK_MULTI_INPUT },
--
2.17.1

View file

@ -0,0 +1,26 @@
From 9100ebd6198c2db95b041a6ffcca6f8070308aa1 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:53:11 -0500
Subject: [PATCH 07/11] sdcard-reader
---
drivers/usb/core/hub.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index cc62707c0251..caed42b72daf 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4150,7 +4150,8 @@ void usb_enable_lpm(struct usb_device *udev)
if (!udev || !udev->parent ||
udev->speed < USB_SPEED_SUPER ||
!udev->lpm_capable ||
- udev->state < USB_STATE_DEFAULT)
+ udev->state < USB_STATE_DEFAULT ||
+ !udev->bos || !udev->bos->ss_cap)
return;
udev->lpm_disable_count--;
--
2.17.1

View file

@ -0,0 +1,272 @@
From fc19b38f066347b2acffe213bfe6c96e745698b2 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:53:31 -0500
Subject: [PATCH 08/11] wifi
---
drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 3 +--
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 5 ++++-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 2 ++
drivers/net/wireless/marvell/mwifiex/fw.h | 1 +
drivers/net/wireless/marvell/mwifiex/main.c | 17 +++++++++++++----
drivers/net/wireless/marvell/mwifiex/main.h | 2 ++
drivers/net/wireless/marvell/mwifiex/pcie.c | 9 +++++++++
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 8 ++++----
.../net/wireless/marvell/mwifiex/sta_cmdresp.c | 11 ++++++++---
drivers/net/wireless/marvell/mwifiex/usb.c | 2 ++
scripts/leaking_addresses.pl | 0
11 files changed, 46 insertions(+), 14 deletions(-)
mode change 100755 => 100644 scripts/leaking_addresses.pl
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
index 042a1d07f686..fc9041f58e9f 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
@@ -200,8 +200,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
do {
/* Check if AMSDU can accommodate this MSDU */
- if ((skb_aggr->len + skb_src->len + LLC_SNAP_LEN) >
- adapter->tx_buf_size)
+ if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN))
break;
skb_src = skb_dequeue(&pra_list->skb_head);
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index adc88433faa8..7376ffa82c63 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -428,7 +428,10 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
mwifiex_dbg(priv->adapter, INFO,
"info: ignore timeout value for IEEE Power Save\n");
- ps_mode = enabled;
+ //ps_mode = enabled;
+
+ mwifiex_dbg(priv->adapter, INFO, "overriding ps_mode to false\n");
+ ps_mode = 0;
return mwifiex_drv_set_power(priv, &ps_mode);
}
diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 60db2b969e20..a15675ef31bd 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -1000,6 +1000,7 @@ mwifiex_cmd_timeout_func(struct timer_list *t)
if (cmd_node->wait_q_enabled) {
adapter->cmd_wait_q.status = -ETIMEDOUT;
mwifiex_cancel_pending_ioctl(adapter);
+ adapter->cmd_sent = false;
}
}
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
@@ -1577,6 +1578,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
adapter->key_api_minor_ver);
break;
case FW_API_VER_ID:
+ case FW_KEY_API_VER_ID:
adapter->fw_api_ver =
api_rev->major_ver;
mwifiex_dbg(adapter, INFO,
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index b73f99dc5a72..d96a0ffc9649 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -1052,6 +1052,7 @@ struct host_cmd_ds_802_11_ps_mode_enh {
enum API_VER_ID {
KEY_API_VER_ID = 1,
FW_API_VER_ID = 2,
+ FW_KEY_API_VER_ID = 4,
};
struct hw_spec_api_rev {
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 20cee5c397fb..13e49a3ae812 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -163,6 +163,7 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter)
spin_lock_irqsave(&adapter->main_proc_lock, flags);
if (adapter->mwifiex_processing) {
adapter->more_task_flag = true;
+ adapter->more_rx_task_flag = true;
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
} else {
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
@@ -171,18 +172,20 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter)
}
EXPORT_SYMBOL_GPL(mwifiex_queue_main_work);
-static void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter)
+void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter)
{
unsigned long flags;
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
if (adapter->rx_processing) {
+ adapter->more_rx_task_flag = true;
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
} else {
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
queue_work(adapter->rx_workqueue, &adapter->rx_work);
}
}
+EXPORT_SYMBOL_GPL(mwifiex_queue_rx_work);
static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
{
@@ -192,6 +195,7 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
if (adapter->rx_processing || adapter->rx_locked) {
+ adapter->more_rx_task_flag = true;
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
goto exit_rx_proc;
} else {
@@ -199,6 +203,7 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
}
+rx_process_start:
/* Check for Rx data */
while ((skb = skb_dequeue(&adapter->rx_data_q))) {
atomic_dec(&adapter->rx_pending);
@@ -220,6 +225,11 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
}
}
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
+ if (adapter->more_rx_task_flag) {
+ adapter->more_rx_task_flag = false;
+ spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
+ goto rx_process_start;
+ }
adapter->rx_processing = false;
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
@@ -283,11 +293,10 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
mwifiex_process_hs_config(adapter);
if (adapter->if_ops.process_int_status)
adapter->if_ops.process_int_status(adapter);
+ if (adapter->rx_work_enabled && adapter->data_received)
+ mwifiex_queue_rx_work(adapter);
}
- if (adapter->rx_work_enabled && adapter->data_received)
- mwifiex_queue_rx_work(adapter);
-
/* Need to wake up the card ? */
if ((adapter->ps_state == PS_STATE_SLEEP) &&
(adapter->pm_wakeup_card_req &&
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index b025ba164412..d4027a803079 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -908,6 +908,7 @@ struct mwifiex_adapter {
spinlock_t main_proc_lock;
u32 mwifiex_processing;
u8 more_task_flag;
+ u8 more_rx_task_flag;
u16 tx_buf_size;
u16 curr_tx_buf_size;
/* sdio single port rx aggregation capability */
@@ -1694,6 +1695,7 @@ void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter);
void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
void mwifiex_fw_dump_event(struct mwifiex_private *priv);
void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
+void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter);
int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
int cmd_type,
struct mwifiex_ds_wakeup_reason *wakeup_reason);
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 3fe81b2a929a..6e734a83e6bf 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -1743,6 +1743,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
}
rx_len = get_unaligned_le16(skb->data);
+
+ if (rx_len == 0) {
+ mwifiex_dbg(adapter, ERROR,
+ "0 byte cmdrsp\n");
+ mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
+ PCI_DMA_FROMDEVICE);
+ return 0;
+ }
+
skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
skb_trim(skb, rx_len);
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 4ed10cf82f9a..f17af83f5669 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -2339,7 +2339,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
if (ret)
return -1;
- if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
+ if (0 && priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
/* Enable IEEE PS by default */
priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
ret = mwifiex_send_cmd(priv,
@@ -2362,8 +2362,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
return -1;
}
- mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REGION_CFG,
- HostCmd_ACT_GEN_GET, 0, NULL, true);
+ //mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REGION_CFG,
+ // HostCmd_ACT_GEN_GET, 0, NULL, true);
}
/* get tx rate */
@@ -2395,7 +2395,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
if (ret)
return -1;
- if (!disable_auto_ds && first_sta &&
+ if (0 && !disable_auto_ds && first_sta &&
priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
/* Enable auto deep sleep */
auto_ds.auto_ds = DEEP_SLEEP_ON;
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
index 69e3b624adbb..884bad677cc3 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
@@ -48,9 +48,14 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
struct host_cmd_ds_802_11_ps_mode_enh *pm;
unsigned long flags;
- mwifiex_dbg(adapter, ERROR,
- "CMD_RESP: cmd %#x error, result=%#x\n",
- resp->command, resp->result);
+ if (resp->command == 271 && resp->result == 2){
+ // ignore this command as the firmware does not support it
+ }
+ else {
+ mwifiex_dbg(adapter, ERROR,
+ "CMD_RESP: cmd %#x error, result=%#x\n",
+ resp->command, resp->result);
+ }
if (adapter->curr_cmd->wait_q_enabled)
adapter->cmd_wait_q.status = -1;
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index 433c6a16870b..a2ff1ee3d230 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -144,6 +144,8 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter,
skb_queue_tail(&adapter->rx_data_q, skb);
adapter->data_received = true;
atomic_inc(&adapter->rx_pending);
+ if (adapter->rx_work_enabled)
+ mwifiex_queue_rx_work(adapter);
break;
default:
mwifiex_dbg(adapter, ERROR,
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
old mode 100755
new mode 100644
--
2.17.1

View file

@ -0,0 +1,753 @@
From a6204ef155dc2c4ad1fd5bb32e06fd48f43f8572 Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:53:53 -0500
Subject: [PATCH 09/11] surface3-power
---
drivers/acpi/Kconfig | 6 +
drivers/acpi/Makefile | 2 +
drivers/acpi/surface3_power.c | 702 ++++++++++++++++++++++++++++++++++
3 files changed, 710 insertions(+)
create mode 100644 drivers/acpi/surface3_power.c
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index dd1eea90f67f..b5a978e6d487 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -498,6 +498,12 @@ config ACPI_EXTLOG
driver adds support for that functionality with corresponding
tracepoint which carries that information to userspace.
+config ACPI_SURFACE3_POWER_OPREGION
+ tristate "Surface 3 battery platform operation region support"
+ help
+ Select this option to enable support for ACPI operation
+ region of the Surface 3 battery platform driver.
+
menuconfig PMIC_OPREGION
bool "PMIC (Power Management Integrated Circuit) operation region support"
help
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 6d59aa109a91..a6f02538cd65 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -103,6 +103,8 @@ obj-$(CONFIG_ACPI_APEI) += apei/
obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o
+obj-$(CONFIG_ACPI_SURFACE3_POWER_OPREGION) += surface3_power.o
+
obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o
obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o
obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o
diff --git a/drivers/acpi/surface3_power.c b/drivers/acpi/surface3_power.c
new file mode 100644
index 000000000000..6d59c7f6e4a5
--- /dev/null
+++ b/drivers/acpi/surface3_power.c
@@ -0,0 +1,702 @@
+/*
+ * Supports for the power IC on the Surface 3 tablet.
+ *
+ * (C) Copyright 2016-2017 Red Hat, Inc
+ * (C) Copyright 2016-2017 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ * (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+/*
+ * This driver has been reverse-engineered by parsing the DSDT of the Surface 3
+ * and looking at the registers of the chips.
+ *
+ * The DSDT allowed to find out that:
+ * - the driver is required for the ACPI BAT0 device to communicate to the chip
+ * through an operation region.
+ * - the various defines for the operation region functions to communicate with
+ * this driver
+ * - the DSM 3f99e367-6220-4955-8b0f-06ef2ae79412 allows to trigger ACPI
+ * events to BAT0 (the code is all available in the DSDT).
+ *
+ * Further findings regarding the 2 chips declared in the MSHW0011 are:
+ * - there are 2 chips declared:
+ * . 0x22 seems to control the ADP1 line status (and probably the charger)
+ * . 0x55 controls the battery directly
+ * - the battery chip uses a SMBus protocol (using plain SMBus allows non
+ * destructive commands):
+ * . the commands/registers used are in the range 0x00..0x7F
+ * . if bit 8 (0x80) is set in the SMBus command, the returned value is the
+ * same as when it is not set. There is a high chance this bit is the
+ * read/write
+ * . the various registers semantic as been deduced by observing the register
+ * dumps.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/freezer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+
+#define POLL_INTERVAL (2 * HZ)
+
+static bool dump_registers;
+module_param_named(dump_registers, dump_registers, bool, 0644);
+MODULE_PARM_DESC(dump_registers,
+ "Dump the SMBus register at probe (debugging only).");
+
+struct mshw0011_data {
+ struct i2c_client *adp1;
+ struct i2c_client *bat0;
+ unsigned short notify_version;
+ struct task_struct *poll_task;
+ bool kthread_running;
+
+ bool charging;
+ bool bat_charging;
+ u8 trip_point;
+ s32 full_capacity;
+};
+
+struct mshw0011_lookup {
+ struct mshw0011_data *cdata;
+ unsigned int n;
+ unsigned int index;
+ int addr;
+};
+
+struct mshw0011_handler_data {
+ struct acpi_connection_info info;
+ struct i2c_client *client;
+};
+
+struct bix {
+ u32 revision;
+ u32 power_unit;
+ u32 design_capacity;
+ u32 last_full_charg_capacity;
+ u32 battery_technology;
+ u32 design_voltage;
+ u32 design_capacity_of_warning;
+ u32 design_capacity_of_low;
+ u32 cycle_count;
+ u32 measurement_accuracy;
+ u32 max_sampling_time;
+ u32 min_sampling_time;
+ u32 max_average_interval;
+ u32 min_average_interval;
+ u32 battery_capacity_granularity_1;
+ u32 battery_capacity_granularity_2;
+ char model[10];
+ char serial[10];
+ char type[10];
+ char OEM[10];
+} __packed;
+
+struct bst {
+ u32 battery_state;
+ s32 battery_present_rate;
+ u32 battery_remaining_capacity;
+ u32 battery_present_voltage;
+} __packed;
+
+struct gsb_command {
+ u8 arg0;
+ u8 arg1;
+ u8 arg2;
+} __packed;
+
+struct gsb_buffer {
+ u8 status;
+ u8 len;
+ u8 ret;
+ union {
+ struct gsb_command cmd;
+ struct bst bst;
+ struct bix bix;
+ } __packed;
+} __packed;
+
+#define ACPI_BATTERY_STATE_DISCHARGING 0x1
+#define ACPI_BATTERY_STATE_CHARGING 0x2
+#define ACPI_BATTERY_STATE_CRITICAL 0x4
+
+#define MSHW0011_CMD_DEST_BAT0 0x01
+#define MSHW0011_CMD_DEST_ADP1 0x03
+
+#define MSHW0011_CMD_BAT0_STA 0x01
+#define MSHW0011_CMD_BAT0_BIX 0x02
+#define MSHW0011_CMD_BAT0_BCT 0x03
+#define MSHW0011_CMD_BAT0_BTM 0x04
+#define MSHW0011_CMD_BAT0_BST 0x05
+#define MSHW0011_CMD_BAT0_BTP 0x06
+#define MSHW0011_CMD_ADP1_PSR 0x07
+#define MSHW0011_CMD_BAT0_PSOC 0x09
+#define MSHW0011_CMD_BAT0_PMAX 0x0a
+#define MSHW0011_CMD_BAT0_PSRC 0x0b
+#define MSHW0011_CMD_BAT0_CHGI 0x0c
+#define MSHW0011_CMD_BAT0_ARTG 0x0d
+
+#define MSHW0011_NOTIFY_GET_VERSION 0x00
+#define MSHW0011_NOTIFY_ADP1 0x01
+#define MSHW0011_NOTIFY_BAT0_BST 0x02
+#define MSHW0011_NOTIFY_BAT0_BIX 0x05
+
+#define MSHW0011_ADP1_REG_PSR 0x04
+
+#define MSHW0011_BAT0_REG_CAPACITY 0x0c
+#define MSHW0011_BAT0_REG_FULL_CHG_CAPACITY 0x0e
+#define MSHW0011_BAT0_REG_DESIGN_CAPACITY 0x40
+#define MSHW0011_BAT0_REG_VOLTAGE 0x08
+#define MSHW0011_BAT0_REG_RATE 0x14
+#define MSHW0011_BAT0_REG_OEM 0x45
+#define MSHW0011_BAT0_REG_TYPE 0x4e
+#define MSHW0011_BAT0_REG_SERIAL_NO 0x56
+#define MSHW0011_BAT0_REG_CYCLE_CNT 0x6e
+
+#define MSHW0011_EV_2_5 0x1ff
+
+static int mshw0011_i2c_read_block(struct i2c_client *client, u8 reg, u8 *buf,
+ int len)
+{
+ int status, i;
+
+ for (i = 0; i < len; i++) {
+ status = i2c_smbus_read_byte_data(client, reg + i);
+ if (status < 0) {
+ buf[i] = 0xff;
+ continue;
+ }
+
+ buf[i] = (u8)status;
+ }
+
+ return 0;
+}
+
+static int
+mshw0011_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
+ unsigned int *ret_value)
+{
+ static const uuid_le mshw0011_guid =
+ GUID_INIT(0x3F99E367, 0x6220, 0x4955,
+ 0x8B, 0x0F, 0x06, 0xEF, 0x2A, 0xE7, 0x94, 0x12);
+ union acpi_object *obj;
+ struct acpi_device *adev;
+ acpi_handle handle;
+ unsigned int i;
+
+ handle = ACPI_HANDLE(&cdata->adp1->dev);
+ if (!handle || acpi_bus_get_device(handle, &adev))
+ return -ENODEV;
+
+ obj = acpi_evaluate_dsm_typed(handle, &mshw0011_guid, arg1, arg2, NULL,
+ ACPI_TYPE_BUFFER);
+ if (!obj) {
+ dev_err(&cdata->adp1->dev, "device _DSM execution failed\n");
+ return -ENODEV;
+ }
+
+ *ret_value = 0;
+ for (i = 0; i < obj->buffer.length; i++)
+ *ret_value |= obj->buffer.pointer[i] << (i * 8);
+
+ ACPI_FREE(obj);
+ return 0;
+}
+
+static const struct bix default_bix = {
+ .revision = 0x00,
+ .power_unit = 0x01,
+ .design_capacity = 0x1dca,
+ .last_full_charg_capacity = 0x1dca,
+ .battery_technology = 0x01,
+ .design_voltage = 0x10df,
+ .design_capacity_of_warning = 0x8f,
+ .design_capacity_of_low = 0x47,
+ .cycle_count = 0xffffffff,
+ .measurement_accuracy = 0x00015f90,
+ .max_sampling_time = 0x03e8,
+ .min_sampling_time = 0x03e8,
+ .max_average_interval = 0x03e8,
+ .min_average_interval = 0x03e8,
+ .battery_capacity_granularity_1 = 0x45,
+ .battery_capacity_granularity_2 = 0x11,
+ .model = "P11G8M",
+ .serial = "",
+ .type = "LION",
+ .OEM = "",
+};
+
+static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
+{
+ struct i2c_client *client = cdata->bat0;
+ char buf[10];
+ int ret;
+
+ *bix = default_bix;
+
+ /* get design capacity */
+ ret = i2c_smbus_read_word_data(client,
+ MSHW0011_BAT0_REG_DESIGN_CAPACITY);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading design capacity: %d\n",
+ ret);
+ return ret;
+ }
+ bix->design_capacity = le16_to_cpu(ret);
+
+ /* get last full charge capacity */
+ ret = i2c_smbus_read_word_data(client,
+ MSHW0011_BAT0_REG_FULL_CHG_CAPACITY);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "Error reading last full charge capacity: %d\n", ret);
+ return ret;
+ }
+ bix->last_full_charg_capacity = le16_to_cpu(ret);
+
+ /* get serial number */
+ ret = mshw0011_i2c_read_block(client, MSHW0011_BAT0_REG_SERIAL_NO,
+ buf, 10);
+ if (ret) {
+ dev_err(&client->dev, "Error reading serial no: %d\n", ret);
+ return ret;
+ }
+ memcpy(bix->serial, buf + 7, 3);
+ memcpy(bix->serial + 3, buf, 6);
+ bix->serial[9] = '\0';
+
+ /* get cycle count */
+ ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
+ return ret;
+ }
+ bix->cycle_count = le16_to_cpu(ret);
+
+ /* get OEM name */
+ ret = mshw0011_i2c_read_block(client, MSHW0011_BAT0_REG_OEM, buf, 4);
+ if (ret) {
+ dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
+ return ret;
+ }
+ memcpy(bix->OEM, buf, 3);
+ bix->OEM[4] = '\0';
+
+ return 0;
+}
+
+static int mshw0011_bst(struct mshw0011_data *cdata, struct bst *bst)
+{
+ struct i2c_client *client = cdata->bat0;
+ int rate, capacity, voltage, state;
+ s16 tmp;
+
+ rate = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_RATE);
+ if (rate < 0)
+ return rate;
+
+ capacity = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CAPACITY);
+ if (capacity < 0)
+ return capacity;
+
+ voltage = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_VOLTAGE);
+ if (voltage < 0)
+ return voltage;
+
+ tmp = le16_to_cpu(rate);
+ bst->battery_present_rate = abs((s32)tmp);
+
+ state = 0;
+ if ((s32) tmp > 0)
+ state |= ACPI_BATTERY_STATE_CHARGING;
+ else if ((s32) tmp < 0)
+ state |= ACPI_BATTERY_STATE_DISCHARGING;
+ bst->battery_state = state;
+
+ bst->battery_remaining_capacity = le16_to_cpu(capacity);
+ bst->battery_present_voltage = le16_to_cpu(voltage);
+
+ return 0;
+}
+
+static int mshw0011_adp_psr(struct mshw0011_data *cdata)
+{
+ struct i2c_client *client = cdata->adp1;
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, MSHW0011_ADP1_REG_PSR);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int mshw0011_isr(struct mshw0011_data *cdata)
+{
+ struct bst bst;
+ struct bix bix;
+ int ret;
+ bool status, bat_status;
+
+ ret = mshw0011_adp_psr(cdata);
+ if (ret < 0)
+ return ret;
+
+ status = ret;
+
+ if (status != cdata->charging)
+ mshw0011_notify(cdata, cdata->notify_version,
+ MSHW0011_NOTIFY_ADP1, &ret);
+
+ cdata->charging = status;
+
+ ret = mshw0011_bst(cdata, &bst);
+ if (ret < 0)
+ return ret;
+
+ bat_status = bst.battery_state;
+
+ if (bat_status != cdata->bat_charging)
+ mshw0011_notify(cdata, cdata->notify_version,
+ MSHW0011_NOTIFY_BAT0_BST, &ret);
+
+ cdata->bat_charging = bat_status;
+
+ ret = mshw0011_bix(cdata, &bix);
+ if (ret < 0)
+ return ret;
+ if (bix.last_full_charg_capacity != cdata->full_capacity)
+ mshw0011_notify(cdata, cdata->notify_version,
+ MSHW0011_NOTIFY_BAT0_BIX, &ret);
+
+ cdata->full_capacity = bix.last_full_charg_capacity;
+
+ return 0;
+}
+
+static int mshw0011_poll_task(void *data)
+{
+ struct mshw0011_data *cdata = data;
+ int ret = 0;
+
+ cdata->kthread_running = true;
+
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ schedule_timeout_interruptible(POLL_INTERVAL);
+ try_to_freeze();
+ ret = mshw0011_isr(data);
+ if (ret)
+ break;
+ }
+
+ cdata->kthread_running = false;
+ return ret;
+}
+
+static acpi_status
+mshw0011_space_handler(u32 function, acpi_physical_address command,
+ u32 bits, u64 *value64,
+ void *handler_context, void *region_context)
+{
+ struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
+ struct mshw0011_handler_data *data = handler_context;
+ struct acpi_connection_info *info = &data->info;
+ struct acpi_resource_i2c_serialbus *sb;
+ struct i2c_client *client = data->client;
+ struct mshw0011_data *cdata = i2c_get_clientdata(client);
+ struct acpi_resource *ares;
+ u32 accessor_type = function >> 16;
+ acpi_status ret;
+ int status = 1;
+
+ ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
+ if (ACPI_FAILURE(ret))
+ return ret;
+
+ if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+ ret = AE_BAD_PARAMETER;
+ goto err;
+ }
+
+ sb = &ares->data.i2c_serial_bus;
+ if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+ ret = AE_BAD_PARAMETER;
+ goto err;
+ }
+
+ if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
+ ret = AE_BAD_PARAMETER;
+ goto err;
+ }
+
+ if (gsb->cmd.arg0 == MSHW0011_CMD_DEST_ADP1 &&
+ gsb->cmd.arg1 == MSHW0011_CMD_ADP1_PSR) {
+ ret = mshw0011_adp_psr(cdata);
+ if (ret >= 0) {
+ status = ret;
+ ret = 0;
+ }
+ goto out;
+ }
+
+ if (gsb->cmd.arg0 != MSHW0011_CMD_DEST_BAT0) {
+ ret = AE_BAD_PARAMETER;
+ goto err;
+ }
+
+ switch (gsb->cmd.arg1) {
+ case MSHW0011_CMD_BAT0_STA:
+ ret = 0;
+ break;
+ case MSHW0011_CMD_BAT0_BIX:
+ ret = mshw0011_bix(cdata, &gsb->bix);
+ break;
+ case MSHW0011_CMD_BAT0_BTP:
+ ret = 0;
+ cdata->trip_point = gsb->cmd.arg2;
+ break;
+ case MSHW0011_CMD_BAT0_BST:
+ ret = mshw0011_bst(cdata, &gsb->bst);
+ break;
+ default:
+ pr_info("command(0x%02x) is not supported.\n", gsb->cmd.arg1);
+ ret = AE_BAD_PARAMETER;
+ goto err;
+ }
+
+ out:
+ gsb->ret = status;
+ gsb->status = 0;
+
+ err:
+ ACPI_FREE(ares);
+ return ret;
+}
+
+static int mshw0011_install_space_handler(struct i2c_client *client)
+{
+ acpi_handle handle;
+ struct mshw0011_handler_data *data;
+ acpi_status status;
+
+ handle = ACPI_HANDLE(&client->dev);
+
+ if (!handle)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(struct mshw0011_handler_data),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->client = client;
+ status = acpi_bus_attach_private_data(handle, (void *)data);
+ if (ACPI_FAILURE(status)) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ status = acpi_install_address_space_handler(handle,
+ ACPI_ADR_SPACE_GSBUS,
+ &mshw0011_space_handler,
+ NULL,
+ data);
+ if (ACPI_FAILURE(status)) {
+ dev_err(&client->dev, "Error installing i2c space handler\n");
+ acpi_bus_detach_private_data(handle);
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ acpi_walk_dep_device_list(handle);
+ return 0;
+}
+
+static void mshw0011_remove_space_handler(struct i2c_client *client)
+{
+ acpi_handle handle = ACPI_HANDLE(&client->dev);
+ struct mshw0011_handler_data *data;
+ acpi_status status;
+
+ if (!handle)
+ return;
+
+ acpi_remove_address_space_handler(handle,
+ ACPI_ADR_SPACE_GSBUS,
+ &mshw0011_space_handler);
+
+ status = acpi_bus_get_private_data(handle, (void **)&data);
+ if (ACPI_SUCCESS(status))
+ kfree(data);
+
+ acpi_bus_detach_private_data(handle);
+}
+
+static int acpi_find_i2c(struct acpi_resource *ares, void *data)
+{
+ struct mshw0011_lookup *lookup = data;
+
+ if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+ return 1;
+
+ if (lookup->n++ == lookup->index && !lookup->addr)
+ lookup->addr = ares->data.i2c_serial_bus.slave_address;
+
+ return 1;
+}
+
+static int mshw0011_i2c_resource_lookup(struct mshw0011_data *cdata,
+ unsigned int index)
+{
+ struct i2c_client *client = cdata->adp1;
+ struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+ struct mshw0011_lookup lookup = {
+ .cdata = cdata,
+ .index = index,
+ };
+ struct list_head res_list;
+ int ret;
+
+ INIT_LIST_HEAD(&res_list);
+
+ ret = acpi_dev_get_resources(adev, &res_list, acpi_find_i2c, &lookup);
+ if (ret < 0)
+ return ret;
+
+ acpi_dev_free_resource_list(&res_list);
+
+ if (!lookup.addr)
+ return -ENOENT;
+
+ return lookup.addr;
+}
+
+static void mshw0011_dump_registers(struct i2c_client *client,
+ struct i2c_client *bat0, u8 end_register)
+{
+ char *rd_buf;
+ char prefix[128];
+ unsigned int length = end_register + 1;
+ int error;
+
+ snprintf(prefix, ARRAY_SIZE(prefix), "%s: ", bat0->name);
+ prefix[127] = '\0';
+
+ rd_buf = kzalloc(length, GFP_KERNEL);
+ error = mshw0011_i2c_read_block(bat0, 0, rd_buf, length);
+ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1,
+ rd_buf, length, true);
+
+ kfree(rd_buf);
+}
+
+static int mshw0011_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct i2c_client *bat0;
+ struct mshw0011_data *data;
+ int error, version, addr;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->adp1 = client;
+ i2c_set_clientdata(client, data);
+
+ addr = mshw0011_i2c_resource_lookup(data, 1);
+ if (addr < 0)
+ return addr;
+
+ bat0 = i2c_new_dummy(client->adapter, addr);
+ if (!bat0)
+ return -ENOMEM;
+
+ data->bat0 = bat0;
+ i2c_set_clientdata(bat0, data);
+
+ if (dump_registers) {
+ mshw0011_dump_registers(client, client, 0xFF);
+ mshw0011_dump_registers(client, bat0, 0x80);
+ }
+
+ error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &version);
+ if (error)
+ goto out_err;
+
+ data->notify_version = version == MSHW0011_EV_2_5;
+
+ data->poll_task = kthread_run(mshw0011_poll_task, data, "mshw0011_adp");
+ if (IS_ERR(data->poll_task)) {
+ error = PTR_ERR(data->poll_task);
+ dev_err(&client->dev, "Unable to run kthread err %d\n", error);
+ goto out_err;
+ }
+
+ error = mshw0011_install_space_handler(client);
+ if (error)
+ goto out_err;
+
+ return 0;
+
+out_err:
+ if (data->kthread_running)
+ kthread_stop(data->poll_task);
+ i2c_unregister_device(data->bat0);
+ return error;
+}
+
+static int mshw0011_remove(struct i2c_client *client)
+{
+ struct mshw0011_data *cdata = i2c_get_clientdata(client);
+
+ mshw0011_remove_space_handler(client);
+
+ if (cdata->kthread_running)
+ kthread_stop(cdata->poll_task);
+
+ i2c_unregister_device(cdata->bat0);
+
+ return 0;
+}
+
+static const struct i2c_device_id mshw0011_id[] = {
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mshw0011_id);
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id mshw0011_acpi_match[] = {
+ { "MSHW0011", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);
+#endif
+
+static struct i2c_driver mshw0011_driver = {
+ .probe = mshw0011_probe,
+ .remove = mshw0011_remove,
+ .id_table = mshw0011_id,
+ .driver = {
+ .name = "mshw0011",
+ .acpi_match_table = ACPI_PTR(mshw0011_acpi_match),
+ },
+};
+module_i2c_driver(mshw0011_driver);
+
+MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+MODULE_DESCRIPTION("mshw0011 driver");
+MODULE_LICENSE("GPL v2");
--
2.17.1

View file

@ -0,0 +1,25 @@
From 9e407a993e67743172e1ad895072fc74b2289f8e Mon Sep 17 00:00:00 2001
From: Jake Day <jake@ninebysix.com>
Date: Sun, 27 Jan 2019 10:54:15 -0500
Subject: [PATCH 10/11] surface-dock
---
drivers/usb/core/quirks.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 8bc35d53408b..11fa56cbd769 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -212,6 +212,8 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
{ USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
+ { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
+
/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
--
2.17.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index aea3d13..8fcbf81 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -39,7 +39,7 @@
#define BR_GROUPFWD_8021AD 0xB801u
/* Path to usermode spanning tree program */
-#define BR_STP_PROG "/sbin/bridge-stp"
+#define BR_STP_PROG "/run/current-system/sw/bin/bridge-stp"
typedef struct bridge_id bridge_id;
typedef struct mac_addr mac_addr;

9569
linux_surface/patches/config Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,14 @@
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 07650ee..934a7a8 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -9,7 +9,8 @@ include scripts/Kbuild.include
#
-__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+__modules := $(sort $(foreach f,$(wildcard $(MODVERDIR)/*.mod),$(shell \
+ grep -h '\.ko$$' '$f')))
modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
PHONY += $(modules)

56
mu-git/default.nix Normal file
View file

@ -0,0 +1,56 @@
{ stdenv, sqlite, pkgconfig, autoreconfHook, pmccabe
, xapian, glib, gmime, texinfo , emacs, guile
, gtk3, gmime3, webkitgtk24x-gtk3, libsoup, icu
, withMug ? false }:
stdenv.mkDerivation rec {
name = "mu-${version}";
version = "git";
src = fetchTarball https://github.com/djcb/mu/archive/master.tar.gz;
# 0.9.18 and 1.0 have 2 failing tests but previously we had no tests
patches = [
./failing_tests.patch
];
# test-utils coredumps so don't run those
postPatch = ''
sed -i -e '/test-utils/d' lib/parser/Makefile.am
'';
buildInputs = [
sqlite xapian glib gmime texinfo emacs gmime3 guile libsoup icu
] ++ stdenv.lib.optionals withMug [ gtk3 webkitgtk24x-gtk3 ];
nativeBuildInputs = [ pkgconfig autoreconfHook pmccabe ];
enableParallelBuilding = true;
preBuild = ''
# Fix mu4e-builddir (set it to $out)
substituteInPlace mu4e/mu4e-meta.el.in \
--replace "@abs_top_builddir@" "$out"
# We install msg2pdf to bin/msg2pdf, fix its location in elisp
substituteInPlace mu4e/mu4e-actions.el \
--replace "/toys/msg2pdf/msg2pdf" "/bin/msg2pdf"
'';
# Install mug and msg2pdf
postInstall = stdenv.lib.optionalString withMug ''
for f in msg2pdf mug ; do
install -m755 toys/$f/$f $out/bin/$f
done
'';
doCheck = true;
meta = with stdenv.lib; {
description = "A collection of utilties for indexing and searching Maildirs";
license = licenses.gpl3Plus;
homepage = http://www.djcbsoftware.nl/code/mu/;
platforms = platforms.mesaPlatforms;
maintainers = with maintainers; [ antono the-kenny peterhoeg ];
};
}

View file

@ -0,0 +1,18 @@
diff --git a/mu/tests/test-mu-query.c b/mu/tests/test-mu-query.c
index 73cbd3f4..46a0b131 100644
--- a/mu/tests/test-mu-query.c
+++ b/mu/tests/test-mu-query.c
@@ -753,10 +753,10 @@ main (int argc, char *argv[])
g_test_add_func ("/mu-query/test-mu-query-sizes",
test_mu_query_sizes);
- g_test_add_func ("/mu-query/test-mu-query-dates-helsinki",
- test_mu_query_dates_helsinki);
- g_test_add_func ("/mu-query/test-mu-query-dates-sydney",
- test_mu_query_dates_sydney);
+ /* g_test_add_func ("/mu-query/test-mu-query-dates-helsinki", */
+ /* test_mu_query_dates_helsinki); */
+ /* g_test_add_func ("/mu-query/test-mu-query-dates-sydney", */
+ /* test_mu_query_dates_sydney); */
g_test_add_func ("/mu-query/test-mu-query-dates-la",
test_mu_query_dates_la);

19
release.nix Normal file
View file

@ -0,0 +1,19 @@
{ ... }:
let
pkgs = import <nixpkgs> { config = { allowUnfree = true; allowBroken = true;}; };
jobs = rec {
linux_surface = pkgs.callPackage ./linux_surface/default.nix {};
mu-git = pkgs.callPackage ./mu-git {};
xdiskusage = pkgs.callPackage ./xdiskusage {};
};
in jobs // {
channel = pkgs.releaseTools.channel {
name = "nixpkgs_local";
src = ./.;
constituents = jobs;
};
}

13
xdiskusage/default.nix Normal file
View file

@ -0,0 +1,13 @@
{ stdenv, fetchurl, fltk }:
stdenv.mkDerivation rec {
name = "xdiskusage";
version = "1.51";
buildInputs = [ fltk ];
src = fetchurl {
url = "http://xdiskusage.sourceforge.net/${name}-${version}.tgz";
sha256 = "1il9200a2yd6023sbmixspvhj4ip6frm8sczjk5zk68j65zl9ckg";
};
}