Add preliminary v5.4 patches
This commit is contained in:
parent
51ba311b8e
commit
9e132617b8
110
patches/5.4/0001-ioremap_uc.patch
Normal file
110
patches/5.4/0001-ioremap_uc.patch
Normal file
|
@ -0,0 +1,110 @@
|
|||
From e595c41258f70ccc9d980683bd6a447f04153d86 Mon Sep 17 00:00:00 2001
|
||||
From: Tuowen Zhao <ztuowen@gmail.com>
|
||||
Date: Wed, 16 Oct 2019 15:06:27 -0600
|
||||
Subject: [PATCH 1/7] ioremap_uc
|
||||
|
||||
---
|
||||
.../driver-api/driver-model/devres.rst | 1 +
|
||||
arch/sparc/include/asm/io_64.h | 1 +
|
||||
drivers/mfd/intel-lpss.c | 2 +-
|
||||
include/linux/io.h | 2 ++
|
||||
lib/devres.c | 19 +++++++++++++++++++
|
||||
5 files changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
|
||||
index a100bef54952..92628fdc2f11 100644
|
||||
--- a/Documentation/driver-api/driver-model/devres.rst
|
||||
+++ b/Documentation/driver-api/driver-model/devres.rst
|
||||
@@ -314,6 +314,7 @@ IOMAP
|
||||
devm_ioport_unmap()
|
||||
devm_ioremap()
|
||||
devm_ioremap_nocache()
|
||||
+ devm_ioremap_uc()
|
||||
devm_ioremap_wc()
|
||||
devm_ioremap_resource() : checks resource, requests memory region, ioremaps
|
||||
devm_iounmap()
|
||||
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
|
||||
index 688911051b44..f4afa301954a 100644
|
||||
--- a/arch/sparc/include/asm/io_64.h
|
||||
+++ b/arch/sparc/include/asm/io_64.h
|
||||
@@ -407,6 +407,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
|
||||
}
|
||||
|
||||
#define ioremap_nocache(X,Y) ioremap((X),(Y))
|
||||
+#define ioremap_uc(X,Y) ioremap((X),(Y))
|
||||
#define ioremap_wc(X,Y) ioremap((X),(Y))
|
||||
#define ioremap_wt(X,Y) ioremap((X),(Y))
|
||||
|
||||
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
|
||||
index bfe4ff337581..b0f0781a6b9c 100644
|
||||
--- a/drivers/mfd/intel-lpss.c
|
||||
+++ b/drivers/mfd/intel-lpss.c
|
||||
@@ -384,7 +384,7 @@ int intel_lpss_probe(struct device *dev,
|
||||
if (!lpss)
|
||||
return -ENOMEM;
|
||||
|
||||
- lpss->priv = devm_ioremap(dev, info->mem->start + LPSS_PRIV_OFFSET,
|
||||
+ lpss->priv = devm_ioremap_uc(dev, info->mem->start + LPSS_PRIV_OFFSET,
|
||||
LPSS_PRIV_SIZE);
|
||||
if (!lpss->priv)
|
||||
return -ENOMEM;
|
||||
diff --git a/include/linux/io.h b/include/linux/io.h
|
||||
index accac822336a..a59834bc0a11 100644
|
||||
--- a/include/linux/io.h
|
||||
+++ b/include/linux/io.h
|
||||
@@ -64,6 +64,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
|
||||
|
||||
void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||
resource_size_t size);
|
||||
+void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
|
||||
+ resource_size_t size);
|
||||
void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
|
||||
resource_size_t size);
|
||||
void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
|
||||
diff --git a/lib/devres.c b/lib/devres.c
|
||||
index 6a0e9bd6524a..17624d35e82d 100644
|
||||
--- a/lib/devres.c
|
||||
+++ b/lib/devres.c
|
||||
@@ -9,6 +9,7 @@
|
||||
enum devm_ioremap_type {
|
||||
DEVM_IOREMAP = 0,
|
||||
DEVM_IOREMAP_NC,
|
||||
+ DEVM_IOREMAP_UC,
|
||||
DEVM_IOREMAP_WC,
|
||||
};
|
||||
|
||||
@@ -39,6 +40,9 @@ static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
|
||||
case DEVM_IOREMAP_NC:
|
||||
addr = ioremap_nocache(offset, size);
|
||||
break;
|
||||
+ case DEVM_IOREMAP_UC:
|
||||
+ addr = ioremap_uc(offset, size);
|
||||
+ break;
|
||||
case DEVM_IOREMAP_WC:
|
||||
addr = ioremap_wc(offset, size);
|
||||
break;
|
||||
@@ -68,6 +72,21 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||
}
|
||||
EXPORT_SYMBOL(devm_ioremap);
|
||||
|
||||
+/**
|
||||
+ * devm_ioremap_uc - Managed ioremap_uc()
|
||||
+ * @dev: Generic device to remap IO address for
|
||||
+ * @offset: Resource address to map
|
||||
+ * @size: Size of map
|
||||
+ *
|
||||
+ * Managed ioremap_uc(). Map is automatically unmapped on driver detach.
|
||||
+ */
|
||||
+void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
|
||||
+ resource_size_t size)
|
||||
+{
|
||||
+ return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_UC);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_ioremap_uc);
|
||||
+
|
||||
/**
|
||||
* devm_ioremap_nocache - Managed ioremap_nocache()
|
||||
* @dev: Generic device to remap IO address for
|
||||
--
|
||||
2.24.0
|
||||
|
27
patches/5.4/0002-hid.patch
Normal file
27
patches/5.4/0002-hid.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 5b13ed4b0c6dccb70cce67a80cc6c83492b58e28 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= <blaz@mxxn.io>
|
||||
Date: Wed, 6 Nov 2019 19:43:26 +0900
|
||||
Subject: [PATCH 2/7] hid
|
||||
|
||||
---
|
||||
drivers/hid/hid-core.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index 2fa3587d974f..e0b241bd3070 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -781,6 +781,10 @@ static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
|
||||
if (usage == 0xff0000c5 && parser->global.report_count == 256 &&
|
||||
parser->global.report_size == 8)
|
||||
parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
|
||||
+
|
||||
+ if (usage == 0xff0000c6 && parser->global.report_count == 1 &&
|
||||
+ parser->global.report_size == 8)
|
||||
+ parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
|
||||
}
|
||||
|
||||
static void hid_scan_collection(struct hid_parser *parser, unsigned type)
|
||||
--
|
||||
2.24.0
|
||||
|
6318
patches/5.4/0003-surface-acpi.patch
Normal file
6318
patches/5.4/0003-surface-acpi.patch
Normal file
File diff suppressed because it is too large
Load diff
359
patches/5.4/0004-surfacebook2-dgpu.patch
Normal file
359
patches/5.4/0004-surfacebook2-dgpu.patch
Normal file
|
@ -0,0 +1,359 @@
|
|||
From 553685a989f06c01aef953dcd9f2ea8f7f8ebf7a Mon Sep 17 00:00:00 2001
|
||||
From: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
Date: Tue, 2 Jul 2019 22:17:46 +0200
|
||||
Subject: [PATCH 4/7] 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 675ec12cbc0e..1cef3c858d24 100644
|
||||
--- a/drivers/platform/x86/Kconfig
|
||||
+++ b/drivers/platform/x86/Kconfig
|
||||
@@ -481,6 +481,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 18f5a4ba7244..725dedf5fbfe 100644
|
||||
--- a/drivers/platform/x86/Makefile
|
||||
+++ b/drivers/platform/x86/Makefile
|
||||
@@ -48,6 +48,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 <linux/acpi.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/moduleparam.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/sysfs.h>
|
||||
+
|
||||
+#include <linux/uaccess.h>
|
||||
+
|
||||
+
|
||||
+#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 "<invalid>";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+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 <luzmaximilian@gmail.com>");
|
||||
+MODULE_DESCRIPTION("Surface Book 2 Hot-Plug System Driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.24.0
|
||||
|
655
patches/5.4/0005-surface3-power.patch
Normal file
655
patches/5.4/0005-surface3-power.patch
Normal file
|
@ -0,0 +1,655 @@
|
|||
From 1fe372a463e7db7bf57acbab2f9456797f6f5451 Mon Sep 17 00:00:00 2001
|
||||
From: qzed <qzed@users.noreply.github.com>
|
||||
Date: Tue, 17 Sep 2019 17:17:56 +0200
|
||||
Subject: [PATCH 5/7] surface3-power
|
||||
|
||||
---
|
||||
drivers/platform/x86/Kconfig | 7 +
|
||||
drivers/platform/x86/Makefile | 1 +
|
||||
drivers/platform/x86/surface3_power.c | 604 ++++++++++++++++++++++++++
|
||||
3 files changed, 612 insertions(+)
|
||||
create mode 100644 drivers/platform/x86/surface3_power.c
|
||||
|
||||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
|
||||
index 1cef3c858d24..b8f019db9a55 100644
|
||||
--- a/drivers/platform/x86/Kconfig
|
||||
+++ b/drivers/platform/x86/Kconfig
|
||||
@@ -1219,6 +1219,13 @@ config SURFACE_3_BUTTON
|
||||
---help---
|
||||
This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
|
||||
|
||||
+config SURFACE_3_POWER_OPREGION
|
||||
+ tristate "Surface 3 battery platform operation region support"
|
||||
+ depends on ACPI && I2C
|
||||
+ help
|
||||
+ Select this option to enable support for ACPI operation
|
||||
+ region of the Surface 3 battery platform driver.
|
||||
+
|
||||
config INTEL_PUNIT_IPC
|
||||
tristate "Intel P-Unit IPC Driver"
|
||||
---help---
|
||||
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
|
||||
index 725dedf5fbfe..705525ff99a7 100644
|
||||
--- a/drivers/platform/x86/Makefile
|
||||
+++ b/drivers/platform/x86/Makefile
|
||||
@@ -86,6 +86,7 @@ obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
|
||||
obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
|
||||
obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
|
||||
+obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o
|
||||
obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o
|
||||
obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o
|
||||
obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
|
||||
diff --git a/drivers/platform/x86/surface3_power.c b/drivers/platform/x86/surface3_power.c
|
||||
new file mode 100644
|
||||
index 000000000000..e0af01a60302
|
||||
--- /dev/null
|
||||
+++ b/drivers/platform/x86/surface3_power.c
|
||||
@@ -0,0 +1,604 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+
|
||||
+/*
|
||||
+ * Supports for the power IC on the Surface 3 tablet.
|
||||
+ *
|
||||
+ * (C) Copyright 2016-2018 Red Hat, Inc
|
||||
+ * (C) Copyright 2016-2018 Benjamin Tissoires <benjamin.tissoires@gmail.com>
|
||||
+ * (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * 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)
|
||||
+
|
||||
+struct mshw0011_data {
|
||||
+ struct i2c_client *adp1;
|
||||
+ struct i2c_client *bat0;
|
||||
+ unsigned short notify_mask;
|
||||
+ 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 BIT(0)
|
||||
+#define ACPI_BATTERY_STATE_CHARGING BIT(1)
|
||||
+#define ACPI_BATTERY_STATE_CRITICAL BIT(2)
|
||||
+
|
||||
+#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_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
|
||||
+ unsigned int *ret_value)
|
||||
+{
|
||||
+ static const guid_t 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 = 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 = ret;
|
||||
+
|
||||
+ /* get serial number */
|
||||
+ ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
|
||||
+ 10, buf);
|
||||
+ if (ret != 10) {
|
||||
+ dev_err(&client->dev, "Error reading serial no: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ snprintf(bix->serial, ARRAY_SIZE(bix->serial),
|
||||
+ "%*pE%*pE", 3, buf + 7, 6, buf);
|
||||
+
|
||||
+ /* 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 = ret;
|
||||
+
|
||||
+ /* get OEM name */
|
||||
+ ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_OEM,
|
||||
+ 4, buf);
|
||||
+ if (ret != 4) {
|
||||
+ dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ snprintf(bix->OEM, ARRAY_SIZE(bix->OEM), "%*pE", 3, buf);
|
||||
+
|
||||
+ 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 = 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 = capacity;
|
||||
+ bst->battery_present_voltage = 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_mask,
|
||||
+ 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_mask,
|
||||
+ 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_mask,
|
||||
+ 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:
|
||||
+ break;
|
||||
+ case MSHW0011_CMD_BAT0_BIX:
|
||||
+ ret = mshw0011_bix(cdata, &gsb->bix);
|
||||
+ break;
|
||||
+ case MSHW0011_CMD_BAT0_BTP:
|
||||
+ 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 mshw0011_probe(struct i2c_client *client)
|
||||
+{
|
||||
+ struct i2c_board_info board_info;
|
||||
+ struct device *dev = &client->dev;
|
||||
+ struct i2c_client *bat0;
|
||||
+
|
||||
+ struct mshw0011_data *data;
|
||||
+ int error, mask;
|
||||
+
|
||||
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data->adp1 = client;
|
||||
+ i2c_set_clientdata(client, data);
|
||||
+
|
||||
+ memset(&board_info, 0, sizeof(board_info));
|
||||
+ strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE);
|
||||
+
|
||||
+ bat0 = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
+ if (!bat0)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data->bat0 = bat0;
|
||||
+ i2c_set_clientdata(bat0, data);
|
||||
+
|
||||
+ error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &mask);
|
||||
+ if (error)
|
||||
+ goto out_err;
|
||||
+
|
||||
+ data->notify_mask = mask == 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 acpi_device_id mshw0011_acpi_match[] = {
|
||||
+ { "MSHW0011", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);
|
||||
+
|
||||
+static struct i2c_driver mshw0011_driver = {
|
||||
+ .probe_new = mshw0011_probe,
|
||||
+ .remove = mshw0011_remove,
|
||||
+ .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.24.0
|
||||
|
24
patches/5.4/0006-surface-lte.patch
Normal file
24
patches/5.4/0006-surface-lte.patch
Normal file
|
@ -0,0 +1,24 @@
|
|||
From 686f6202a26afc35e9ee45e2106207f6a50d3bac Mon Sep 17 00:00:00 2001
|
||||
From: qzed <qzed@users.noreply.github.com>
|
||||
Date: Tue, 17 Sep 2019 17:21:43 +0200
|
||||
Subject: [PATCH 6/7] surface-lte
|
||||
|
||||
---
|
||||
drivers/usb/serial/qcserial.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
|
||||
index 613f91add03d..e1428222dd73 100644
|
||||
--- a/drivers/usb/serial/qcserial.c
|
||||
+++ b/drivers/usb/serial/qcserial.c
|
||||
@@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */
|
||||
{DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */
|
||||
{DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */
|
||||
+ {DEVICE_SWI(0x045e, 0x096e)}, /* Microsoft Surface Go LTE */
|
||||
|
||||
/* Huawei devices */
|
||||
{DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
|
||||
--
|
||||
2.24.0
|
||||
|
267
patches/5.4/0007-wifi.patch
Normal file
267
patches/5.4/0007-wifi.patch
Normal file
|
@ -0,0 +1,267 @@
|
|||
From 4336f2d8b36012ff7eac888dee18e9d35bbff90e Mon Sep 17 00:00:00 2001
|
||||
From: qzed <qzed@users.noreply.github.com>
|
||||
Date: Wed, 18 Sep 2019 03:18:25 +0200
|
||||
Subject: [PATCH 7/7] 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 | 10 ++++++----
|
||||
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 | 4 ++--
|
||||
.../net/wireless/marvell/mwifiex/sta_cmdresp.c | 10 +++++++---
|
||||
drivers/net/wireless/marvell/mwifiex/usb.c | 2 ++
|
||||
scripts/leaking_addresses.pl | 0
|
||||
11 files changed, 47 insertions(+), 16 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 088612438530..4386e657dfdb 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c
|
||||
@@ -198,8 +198,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 d89684168500..1545bae9d6cf 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
|
||||
@@ -437,7 +437,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 e8788c35a453..82d25b3ca914 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
|
||||
@@ -1004,6 +1004,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) {
|
||||
@@ -1011,11 +1012,11 @@ mwifiex_cmd_timeout_func(struct timer_list *t)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (adapter->if_ops.device_dump)
|
||||
- adapter->if_ops.device_dump(adapter);
|
||||
+ //if (adapter->if_ops.device_dump)
|
||||
+ // adapter->if_ops.device_dump(adapter);
|
||||
|
||||
- if (adapter->if_ops.card_reset)
|
||||
- adapter->if_ops.card_reset(adapter);
|
||||
+ //if (adapter->if_ops.card_reset)
|
||||
+ // adapter->if_ops.card_reset(adapter);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1578,6 +1579,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 1fb76d2f5d3f..fb32379da99d 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 a9657ae6d782..ba99d84a31ef 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,16 +172,18 @@ 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)
|
||||
{
|
||||
spin_lock_bh(&adapter->rx_proc_lock);
|
||||
if (adapter->rx_processing) {
|
||||
+ adapter->more_rx_task_flag = true;
|
||||
spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
} else {
|
||||
spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
queue_work(adapter->rx_workqueue, &adapter->rx_work);
|
||||
}
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(mwifiex_queue_rx_work);
|
||||
|
||||
static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
@@ -189,6 +192,7 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
|
||||
|
||||
spin_lock_bh(&adapter->rx_proc_lock);
|
||||
if (adapter->rx_processing || adapter->rx_locked) {
|
||||
+ adapter->more_rx_task_flag = true;
|
||||
spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
goto exit_rx_proc;
|
||||
} else {
|
||||
@@ -196,6 +200,7 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
|
||||
spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
}
|
||||
|
||||
+rx_process_start:
|
||||
/* Check for Rx data */
|
||||
while ((skb = skb_dequeue(&adapter->rx_data_q))) {
|
||||
atomic_dec(&adapter->rx_pending);
|
||||
@@ -217,6 +222,11 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
}
|
||||
spin_lock_bh(&adapter->rx_proc_lock);
|
||||
+ if (adapter->more_rx_task_flag) {
|
||||
+ adapter->more_rx_task_flag = false;
|
||||
+ spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
+ goto rx_process_start;
|
||||
+ }
|
||||
adapter->rx_processing = false;
|
||||
spin_unlock_bh(&adapter->rx_proc_lock);
|
||||
|
||||
@@ -280,11 +290,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 095837fba300..5dca5c25c601 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/main.h
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
|
||||
@@ -909,6 +909,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 */
|
||||
@@ -1695,6 +1696,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 eff06d59e9df..76e76a6a7ab1 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
|
||||
@@ -1739,6 +1739,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..485360e8534b 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
|
||||
@@ -30,8 +30,8 @@ static bool drcs;
|
||||
module_param(drcs, bool, 0644);
|
||||
MODULE_PARM_DESC(drcs, "multi-channel operation:1, single-channel operation:0");
|
||||
|
||||
-static bool disable_auto_ds;
|
||||
-module_param(disable_auto_ds, bool, 0);
|
||||
+static bool disable_auto_ds = 1;
|
||||
+module_param(disable_auto_ds, bool, 0644);
|
||||
MODULE_PARM_DESC(disable_auto_ds,
|
||||
"deepsleep enabled=0(default), deepsleep disabled=1");
|
||||
/*
|
||||
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
|
||||
index 20c206da0631..0e58da83417c 100644
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
|
||||
@@ -47,9 +47,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct host_cmd_ds_802_11_ps_mode_enh *pm;
|
||||
|
||||
- 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 c2365eeb7016..0a219ba378dd 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.24.0
|
||||
|
Loading…
Reference in a new issue