diff mbox

STI problem and workaround for Dell XPS 13 (Skylake, 2016) / Broadcom BCM4350

Message ID CADjb_WTD89V_UMUmz3yMQraFLTvccgUgFqAd0KJyT_1+8s+txw@mail.gmail.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Chen Yu March 4, 2016, 7:30 a.m. UTC
On Fri, Mar 4, 2016 at 9:41 AM, yu chen <yu.chen.surf@gmail.com> wrote:
> On Thu, Mar 3, 2016 at 3:16 PM, Tamas Papp <tkpapp@gmail.com> wrote:
>> On Wed, Mar 02 2016, yu chen wrote:
>>
>>> Currently the  0000:3c and 0000:3a might have the same pnp object name PXSX,
>>> unfortunately  the 'echo' will find the first math device in the
>>> wakable list, and maybe
>>>  0000:3c was probed before 0000:3a, so... maybe this is a weakness.
>>>
>>> Maybe you can disabled the wakable feature directly in device sysfs,
>>> for example,
>>> echo 0 > /sys/devices/pci0000:00/0000:3a:00.0/power/wakeup,
>>> you might need to find out where 0000:3a:00.0 is.
>>
>> I tried that, but the module has problems after wakeup. I have to remove
>> and insert it again with modprobe.
>>
>> Still, this is an OK workaround, thanks for the help. I still don't know
>> if I should file this as a bug, and if yes, where.
>>
> Does the following fix make sense for you:
>
> cat /proc/acpi/wakeup
> PXSX:0      S4    *enabled   pci:0000:3a:00.0
> then you need to echo PXSX:0 to disable it,
> and for 3c, it would be PXSX:1

plz find attached the trival patch for it
diff mbox

Patch

Index: linux_for_test/drivers/acpi/proc.c
===================================================================
--- linux_for_test.orig/drivers/acpi/proc.c	2016-03-04 10:59:04.576405039 +0800
+++ linux_for_test/drivers/acpi/proc.c	2016-03-04 12:06:24.368340465 +0800
@@ -33,10 +33,14 @@ 
 
 		if (!dev->wakeup.flags.valid)
 			continue;
-
-		seq_printf(seq, "%s\t  S%d\t",
-			   dev->pnp.bus_id,
-			   (u32) dev->wakeup.sleep_state);
+		if (dev->pnp.bus_sub_id >= 0)
+			seq_printf(seq, "%s:%d\t  S%d\t",
+				    dev->pnp.bus_id, dev->pnp.bus_sub_id,
+				    (u32) dev->wakeup.sleep_state);
+		else
+			seq_printf(seq, "%s\t  S%d\t",
+				    dev->pnp.bus_id,
+				    (u32) dev->wakeup.sleep_state);
 
 		mutex_lock(&dev->physical_node_lock);
 
@@ -96,15 +100,23 @@ 
 				size_t count, loff_t * ppos)
 {
 	struct list_head *node, *next;
-	char strbuf[5];
-	char str[5] = "";
+	char strbuf[7];
+	char str[7] = "";
+	int sub_id = -1;
+	char *split;
 
-	if (count > 4)
-		count = 4;
+	if (count > 6)
+		count = 6;
 
 	if (copy_from_user(strbuf, buffer, count))
 		return -EFAULT;
 	strbuf[count] = '\0';
+	split = strstr(strbuf, ":");
+	if (split) {
+		*split = '\0';
+		split++;
+		sscanf(split, "%d", &sub_id);
+	}
 	sscanf(strbuf, "%s", str);
 
 	mutex_lock(&acpi_device_lock);
@@ -114,7 +126,8 @@ 
 		if (!dev->wakeup.flags.valid)
 			continue;
 
-		if (!strncmp(dev->pnp.bus_id, str, 4)) {
+		if (!strncmp(dev->pnp.bus_id, str, 4) &&
+		    (sub_id == -1 || sub_id == dev->pnp.bus_sub_id)) {
 			if (device_can_wakeup(&dev->dev)) {
 				bool enable = !device_may_wakeup(&dev->dev);
 				device_set_wakeup_enable(&dev->dev, enable);
Index: linux_for_test/drivers/acpi/scan.c
===================================================================
--- linux_for_test.orig/drivers/acpi/scan.c	2016-03-04 10:59:04.576405039 +0800
+++ linux_for_test/drivers/acpi/scan.c	2016-03-04 14:47:08.532186306 +0800
@@ -607,6 +607,34 @@ 
 	put_device(&adev->dev);
 }
 
+#define MAX_SAME_NAME	100
+static void _wake_device_add(struct acpi_device *device)
+{
+	struct list_head *node, *next;
+	int max_idx = -1;
+
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device *dev =
+		    container_of(node, struct acpi_device, wakeup_list);
+
+		if (!dev->wakeup.flags.valid)
+			continue;
+
+		if (!strncmp(dev->pnp.bus_id, device->pnp.bus_id, 4)) {
+			if (dev->pnp.bus_sub_id == -1)
+				dev->pnp.bus_sub_id = 0;
+			if (dev->pnp.bus_sub_id > max_idx)
+				max_idx = dev->pnp.bus_sub_id;
+		}
+	}
+
+	if (max_idx >= MAX_SAME_NAME)
+		pr_err("Too many devices of the same name.\n");
+
+	device->pnp.bus_sub_id = (max_idx >= 0) ? (max_idx + 1) : max_idx;
+	list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
+}
+
 int acpi_device_add(struct acpi_device *device,
 		    void (*release)(struct device *))
 {
@@ -671,7 +699,7 @@ 
 		list_add_tail(&device->node, &device->parent->children);
 
 	if (device->wakeup.flags.valid)
-		list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
+		_wake_device_add(device);
 	mutex_unlock(&acpi_device_lock);
 
 	if (device->parent)
Index: linux_for_test/include/acpi/acpi_bus.h
===================================================================
--- linux_for_test.orig/include/acpi/acpi_bus.h	2016-03-04 10:59:04.576405039 +0800
+++ linux_for_test/include/acpi/acpi_bus.h	2016-03-04 12:03:51.064342915 +0800
@@ -241,6 +241,7 @@ 
 
 struct acpi_device_pnp {
 	acpi_bus_id bus_id;		/* Object name */
+	int bus_sub_id;			/* Sub object index */
 	struct acpi_pnp_type type;	/* ID type */
 	acpi_bus_address bus_address;	/* _ADR */
 	char *unique_id;		/* _UID */