All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code
@ 2019-10-18 19:41 Hans de Goede
  2019-10-18 19:41 ` [PATCH 2/5] ACPI: button: Allow disabling LID support with the lid_init_state module option Hans de Goede
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Hans de Goede @ 2019-10-18 19:41 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown
  Cc: Hans de Goede, Andy Shevchenko, Mika Westerberg, linux-acpi

Replace the weird strncmp() calls in param_set_lid_init_state(),
which look to me like they will also accept things like "opennnn"
to use sysfs_match_string instead.

Also rewrite param_get_lid_init_state() using the new lid_init_state_str
array. Instead of doing a straightforward one line replacement, e.g. :
  return sprintf(buffer, lid_init_state_str[lid_init_state]);
print all possible values, putting [] around the selected value, so
that users can easily find out what the possible values are.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/button.c | 62 ++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 4a2cde2c536a..121d747a840c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -44,9 +44,17 @@
 #define ACPI_BUTTON_DEVICE_NAME_LID	"Lid Switch"
 #define ACPI_BUTTON_TYPE_LID		0x05
 
-#define ACPI_BUTTON_LID_INIT_IGNORE	0x00
-#define ACPI_BUTTON_LID_INIT_OPEN	0x01
-#define ACPI_BUTTON_LID_INIT_METHOD	0x02
+enum {
+	ACPI_BUTTON_LID_INIT_IGNORE,
+	ACPI_BUTTON_LID_INIT_OPEN,
+	ACPI_BUTTON_LID_INIT_METHOD,
+};
+
+static const char * const lid_init_state_str[] = {
+	[ACPI_BUTTON_LID_INIT_IGNORE]		= "ignore",
+	[ACPI_BUTTON_LID_INIT_OPEN]		= "open",
+	[ACPI_BUTTON_LID_INIT_METHOD]		= "method",
+};
 
 #define _COMPONENT		ACPI_BUTTON_COMPONENT
 ACPI_MODULE_NAME("button");
@@ -578,36 +586,30 @@ static int acpi_button_remove(struct acpi_device *device)
 static int param_set_lid_init_state(const char *val,
 				    const struct kernel_param *kp)
 {
-	int result = 0;
-
-	if (!strncmp(val, "open", sizeof("open") - 1)) {
-		lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
-		pr_info("Notify initial lid state as open\n");
-	} else if (!strncmp(val, "method", sizeof("method") - 1)) {
-		lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
-		pr_info("Notify initial lid state with _LID return value\n");
-	} else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {
-		lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;
-		pr_info("Do not notify initial lid state\n");
-	} else
-		result = -EINVAL;
-	return result;
+	int i;
+
+	i = sysfs_match_string(lid_init_state_str, val);
+	if (i < 0)
+		return i;
+
+	lid_init_state = i;
+	pr_info("Initial lid state set to '%s'\n", lid_init_state_str[i]);
+	return 0;
 }
 
-static int param_get_lid_init_state(char *buffer,
-				    const struct kernel_param *kp)
+static int param_get_lid_init_state(char *buf, const struct kernel_param *kp)
 {
-	switch (lid_init_state) {
-	case ACPI_BUTTON_LID_INIT_OPEN:
-		return sprintf(buffer, "open");
-	case ACPI_BUTTON_LID_INIT_METHOD:
-		return sprintf(buffer, "method");
-	case ACPI_BUTTON_LID_INIT_IGNORE:
-		return sprintf(buffer, "ignore");
-	default:
-		return sprintf(buffer, "invalid");
-	}
-	return 0;
+	int i, c = 0;
+
+	for (i = 0; i < ARRAY_SIZE(lid_init_state_str); i++)
+		if (i == lid_init_state)
+			c += sprintf(buf + c, "[%s] ", lid_init_state_str[i]);
+		else
+			c += sprintf(buf + c, "%s ", lid_init_state_str[i]);
+
+	buf[c - 1] = '\n'; /* Replace the final space with a newline */
+
+	return c;
 }
 
 module_param_call(lid_init_state,
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] ACPI: button: Allow disabling LID support with the lid_init_state module option
  2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
@ 2019-10-18 19:41 ` Hans de Goede
  2019-10-18 19:41 ` [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table Hans de Goede
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2019-10-18 19:41 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown
  Cc: Hans de Goede, Andy Shevchenko, Mika Westerberg, linux-acpi

Add a new "disabled" value for the lid_init_state module option, which can
be used to disable LID support on devices where it is completely broken.

Sometimes devices seem to spontaneously suspend and the cause for this is
not clear. The LID switch is known to be one possible cause for this,
this commit allows easily disabling the LID switch for testing if it
is the cause.

For example some devices which do not even have a lid, still have a LID
device in their ACPI tables, pointing to a floating GPIO.

This is not really related to the initial LID state, but re-using the
existing option keeps things simple and it will make it much easier to
add DMI quirks which can either disable the LID completely or set another
non-default lid_init_state value, both of which are necessary on some
devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/button.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 121d747a840c..7f69d8d1905b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -48,12 +48,14 @@ enum {
 	ACPI_BUTTON_LID_INIT_IGNORE,
 	ACPI_BUTTON_LID_INIT_OPEN,
 	ACPI_BUTTON_LID_INIT_METHOD,
+	ACPI_BUTTON_LID_INIT_DISABLED,
 };
 
 static const char * const lid_init_state_str[] = {
 	[ACPI_BUTTON_LID_INIT_IGNORE]		= "ignore",
 	[ACPI_BUTTON_LID_INIT_OPEN]		= "open",
 	[ACPI_BUTTON_LID_INIT_METHOD]		= "method",
+	[ACPI_BUTTON_LID_INIT_DISABLED]		= "disabled",
 };
 
 #define _COMPONENT		ACPI_BUTTON_COMPONENT
@@ -480,7 +482,9 @@ static int acpi_button_add(struct acpi_device *device)
 	char *name, *class;
 	int error;
 
-	if (!strcmp(hid, ACPI_BUTTON_HID_LID) && dmi_check_system(lid_blacklst))
+	if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
+	    (dmi_check_system(lid_blacklst) ||
+	     lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED))
 		return -ENODEV;
 
 	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table
  2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
  2019-10-18 19:41 ` [PATCH 2/5] ACPI: button: Allow disabling LID support with the lid_init_state module option Hans de Goede
@ 2019-10-18 19:41 ` Hans de Goede
  2019-10-21  9:08   ` Andy Shevchenko
  2019-10-18 19:41 ` [PATCH 4/5] ACPI: button: Add DMI quirk for Medion Akoya E2215T Hans de Goede
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Hans de Goede @ 2019-10-18 19:41 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown
  Cc: Hans de Goede, Andy Shevchenko, Mika Westerberg, linux-acpi

Commit 3540c32a9ae4 ("ACPI / button: Add quirks for initial lid state
notification") added 3 different modes to the LID handling code to deal
with various buggy implementations.

Until now users which need one of the 2 non-default modes to get their
hw to work have to pass a kernel commandline option for this.

E.g. https://bugzilla.kernel.org/show_bug.cgi?id=106151 was closed with a
note that the user has to add "button.lid_init_state=open" to the kernel
commandline to get the LID code to not cause undesirable suspends on his
Samsung N210 Plus.

This commit modifies the existing lid_blacklst dmi table so that it can
be used not only to completely disable the LID code on devices where
the ACPI tables are broken beyond repair, but also to select one of the 2
non default LID handling modes on devices where this is necessary.

This will allow us to add quirks to make the LID work OOTB on broken
devices. Getting this working OOTB is esp. important because the typical
breakage is false LID closed reporting, causing undesirable suspends which
basically make the system unusable.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/button.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 7f69d8d1905b..6e8a155f355d 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -75,18 +75,16 @@ static const struct acpi_device_id button_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, button_device_ids);
 
-/*
- * Some devices which don't even have a lid in anyway have a broken _LID
- * method (e.g. pointing to a floating gpio pin) causing spurious LID events.
- */
-static const struct dmi_system_id lid_blacklst[] = {
+/* Please keep this list sorted alphabetically by vendor and model */
+static const struct dmi_system_id dmi_lid_quirks[] = {
 	{
-		/* GP-electronic T701 */
+		/* GP-electronic T701, _LID method points to a floating GPIO */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
 			DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
 		},
+		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
 	},
 	{}
 };
@@ -128,7 +126,7 @@ struct acpi_button {
 
 static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
-static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
+static int lid_init_state = -1;
 
 static unsigned long lid_report_interval __read_mostly = 500;
 module_param(lid_report_interval, ulong, 0644);
@@ -483,8 +481,7 @@ static int acpi_button_add(struct acpi_device *device)
 	int error;
 
 	if (!strcmp(hid, ACPI_BUTTON_HID_LID) &&
-	    (dmi_check_system(lid_blacklst) ||
-	     lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED))
+	     lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED)
 		return -ENODEV;
 
 	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
@@ -623,6 +620,16 @@ MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
 
 static int acpi_button_register_driver(struct acpi_driver *driver)
 {
+	const struct dmi_system_id *dmi_id;
+
+	if (lid_init_state == -1) {
+		dmi_id = dmi_first_match(dmi_lid_quirks);
+		if (dmi_id)
+			lid_init_state = (long)dmi_id->driver_data;
+		else
+			lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
+	}
+
 	/*
 	 * Modules such as nouveau.ko and i915.ko have a link time dependency
 	 * on acpi_lid_open(), and would therefore not be loadable on ACPI
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] ACPI: button: Add DMI quirk for Medion Akoya E2215T
  2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
  2019-10-18 19:41 ` [PATCH 2/5] ACPI: button: Allow disabling LID support with the lid_init_state module option Hans de Goede
  2019-10-18 19:41 ` [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table Hans de Goede
@ 2019-10-18 19:41 ` Hans de Goede
  2019-10-18 19:41 ` [PATCH 5/5] ACPI: button: Remove unused acpi_lid_notifier_[un]register functions Hans de Goede
  2019-10-21  9:09 ` [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Andy Shevchenko
  4 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2019-10-18 19:41 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown
  Cc: Hans de Goede, Andy Shevchenko, Mika Westerberg, linux-acpi

The Medion Akoya E2215T's ACPI _LID implementation is quite broken:

1. For notifications it uses an ActiveLow Edge GpioInt, rather then
an ActiveBoth one, meaning that the device is only notified when the
lid is closed, not when it is opened.

2. Matching with this its _LID method simply always returns 0 (closed)

In order for the Linux LID code to work properly with this implementation,
the lid_init_state selection needs to be set to ACPI_BUTTON_LID_INIT_OPEN.

This commit adds a DMI quirk for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/button.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 6e8a155f355d..3021afc77fc2 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -86,6 +86,17 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
 		},
 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
 	},
+	{
+		/*
+		 * Medion Akoya E2215T, notification of the LID device only
+		 * happens on close, not on open and _LID always returns closed.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "E2215T MD60198"),
+		},
+		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
+	},
 	{}
 };
 
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] ACPI: button: Remove unused acpi_lid_notifier_[un]register functions
  2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
                   ` (2 preceding siblings ...)
  2019-10-18 19:41 ` [PATCH 4/5] ACPI: button: Add DMI quirk for Medion Akoya E2215T Hans de Goede
@ 2019-10-18 19:41 ` Hans de Goede
  2019-10-21  9:09 ` [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Andy Shevchenko
  4 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2019-10-18 19:41 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown
  Cc: Hans de Goede, Andy Shevchenko, Mika Westerberg, linux-acpi

There are no users of the acpi_lid_notifier_[un]register functions,
so lets remove them.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/button.c | 27 +--------------------------
 include/acpi/button.h | 12 ------------
 2 files changed, 1 insertion(+), 38 deletions(-)

diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 3021afc77fc2..117be25ef578 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -135,7 +135,6 @@ struct acpi_button {
 	bool suspended;
 };
 
-static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
 static struct acpi_device *lid_device;
 static int lid_init_state = -1;
 
@@ -165,7 +164,6 @@ static int acpi_lid_evaluate_state(struct acpi_device *device)
 static int acpi_lid_notify_state(struct acpi_device *device, int state)
 {
 	struct acpi_button *button = acpi_driver_data(device);
-	int ret;
 	ktime_t next_report;
 	bool do_update;
 
@@ -242,18 +240,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
 		button->last_time = ktime_get();
 	}
 
-	ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
-	if (ret == NOTIFY_DONE)
-		ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
-						   device);
-	if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
-		/*
-		 * It is also regarded as success if the notifier_chain
-		 * returns NOTIFY_OK or NOTIFY_DONE.
-		 */
-		ret = 0;
-	}
-	return ret;
+	return 0;
 }
 
 static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
@@ -350,18 +337,6 @@ static int acpi_button_remove_fs(struct acpi_device *device)
 /* --------------------------------------------------------------------------
                                 Driver Interface
    -------------------------------------------------------------------------- */
-int acpi_lid_notifier_register(struct notifier_block *nb)
-{
-	return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
-}
-EXPORT_SYMBOL(acpi_lid_notifier_register);
-
-int acpi_lid_notifier_unregister(struct notifier_block *nb)
-{
-	return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
-}
-EXPORT_SYMBOL(acpi_lid_notifier_unregister);
-
 int acpi_lid_open(void)
 {
 	if (!lid_device)
diff --git a/include/acpi/button.h b/include/acpi/button.h
index 3a2b8535dec6..340da7784cc8 100644
--- a/include/acpi/button.h
+++ b/include/acpi/button.h
@@ -2,21 +2,9 @@
 #ifndef ACPI_BUTTON_H
 #define ACPI_BUTTON_H
 
-#include <linux/notifier.h>
-
 #if IS_ENABLED(CONFIG_ACPI_BUTTON)
-extern int acpi_lid_notifier_register(struct notifier_block *nb);
-extern int acpi_lid_notifier_unregister(struct notifier_block *nb);
 extern int acpi_lid_open(void);
 #else
-static inline int acpi_lid_notifier_register(struct notifier_block *nb)
-{
-	return 0;
-}
-static inline int acpi_lid_notifier_unregister(struct notifier_block *nb)
-{
-	return 0;
-}
 static inline int acpi_lid_open(void)
 {
 	return 1;
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table
  2019-10-18 19:41 ` [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table Hans de Goede
@ 2019-10-21  9:08   ` Andy Shevchenko
  2019-10-24 17:44     ` Hans de Goede
  0 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2019-10-21  9:08 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Rafael J . Wysocki, Len Brown, Mika Westerberg, linux-acpi

On Fri, Oct 18, 2019 at 09:41:13PM +0200, Hans de Goede wrote:
> Commit 3540c32a9ae4 ("ACPI / button: Add quirks for initial lid state
> notification") added 3 different modes to the LID handling code to deal
> with various buggy implementations.
> 
> Until now users which need one of the 2 non-default modes to get their
> hw to work have to pass a kernel commandline option for this.
> 
> E.g. https://bugzilla.kernel.org/show_bug.cgi?id=106151 was closed with a
> note that the user has to add "button.lid_init_state=open" to the kernel
> commandline to get the LID code to not cause undesirable suspends on his
> Samsung N210 Plus.
> 
> This commit modifies the existing lid_blacklst dmi table so that it can
> be used not only to completely disable the LID code on devices where
> the ACPI tables are broken beyond repair, but also to select one of the 2
> non default LID handling modes on devices where this is necessary.
> 
> This will allow us to add quirks to make the LID work OOTB on broken
> devices. Getting this working OOTB is esp. important because the typical
> breakage is false LID closed reporting, causing undesirable suspends which
> basically make the system unusable.

> +static int lid_init_state = -1;

>  static int acpi_button_register_driver(struct acpi_driver *driver)
>  {
> +	const struct dmi_system_id *dmi_id;
> +
> +	if (lid_init_state == -1) {
> +		dmi_id = dmi_first_match(dmi_lid_quirks);
> +		if (dmi_id)

> +			lid_init_state = (long)dmi_id->driver_data;

I would rather see here (intptr_t), though up to you and Rafael.
Or mark a variable long itself?

> +		else
> +			lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;

Can't we simple default the value to this?

> +	}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code
  2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
                   ` (3 preceding siblings ...)
  2019-10-18 19:41 ` [PATCH 5/5] ACPI: button: Remove unused acpi_lid_notifier_[un]register functions Hans de Goede
@ 2019-10-21  9:09 ` Andy Shevchenko
  4 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2019-10-21  9:09 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Rafael J . Wysocki, Len Brown, Mika Westerberg, linux-acpi

On Fri, Oct 18, 2019 at 09:41:11PM +0200, Hans de Goede wrote:
> Replace the weird strncmp() calls in param_set_lid_init_state(),
> which look to me like they will also accept things like "opennnn"
> to use sysfs_match_string instead.
> 
> Also rewrite param_get_lid_init_state() using the new lid_init_state_str
> array. Instead of doing a straightforward one line replacement, e.g. :
>   return sprintf(buffer, lid_init_state_str[lid_init_state]);
> print all possible values, putting [] around the selected value, so
> that users can easily find out what the possible values are.

FWIW, after settling on the comment on one of the patches,
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
for entire series.

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/acpi/button.c | 62 ++++++++++++++++++++++---------------------
>  1 file changed, 32 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index 4a2cde2c536a..121d747a840c 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -44,9 +44,17 @@
>  #define ACPI_BUTTON_DEVICE_NAME_LID	"Lid Switch"
>  #define ACPI_BUTTON_TYPE_LID		0x05
>  
> -#define ACPI_BUTTON_LID_INIT_IGNORE	0x00
> -#define ACPI_BUTTON_LID_INIT_OPEN	0x01
> -#define ACPI_BUTTON_LID_INIT_METHOD	0x02
> +enum {
> +	ACPI_BUTTON_LID_INIT_IGNORE,
> +	ACPI_BUTTON_LID_INIT_OPEN,
> +	ACPI_BUTTON_LID_INIT_METHOD,
> +};
> +
> +static const char * const lid_init_state_str[] = {
> +	[ACPI_BUTTON_LID_INIT_IGNORE]		= "ignore",
> +	[ACPI_BUTTON_LID_INIT_OPEN]		= "open",
> +	[ACPI_BUTTON_LID_INIT_METHOD]		= "method",
> +};
>  
>  #define _COMPONENT		ACPI_BUTTON_COMPONENT
>  ACPI_MODULE_NAME("button");
> @@ -578,36 +586,30 @@ static int acpi_button_remove(struct acpi_device *device)
>  static int param_set_lid_init_state(const char *val,
>  				    const struct kernel_param *kp)
>  {
> -	int result = 0;
> -
> -	if (!strncmp(val, "open", sizeof("open") - 1)) {
> -		lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
> -		pr_info("Notify initial lid state as open\n");
> -	} else if (!strncmp(val, "method", sizeof("method") - 1)) {
> -		lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
> -		pr_info("Notify initial lid state with _LID return value\n");
> -	} else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {
> -		lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;
> -		pr_info("Do not notify initial lid state\n");
> -	} else
> -		result = -EINVAL;
> -	return result;
> +	int i;
> +
> +	i = sysfs_match_string(lid_init_state_str, val);
> +	if (i < 0)
> +		return i;
> +
> +	lid_init_state = i;
> +	pr_info("Initial lid state set to '%s'\n", lid_init_state_str[i]);
> +	return 0;
>  }
>  
> -static int param_get_lid_init_state(char *buffer,
> -				    const struct kernel_param *kp)
> +static int param_get_lid_init_state(char *buf, const struct kernel_param *kp)
>  {
> -	switch (lid_init_state) {
> -	case ACPI_BUTTON_LID_INIT_OPEN:
> -		return sprintf(buffer, "open");
> -	case ACPI_BUTTON_LID_INIT_METHOD:
> -		return sprintf(buffer, "method");
> -	case ACPI_BUTTON_LID_INIT_IGNORE:
> -		return sprintf(buffer, "ignore");
> -	default:
> -		return sprintf(buffer, "invalid");
> -	}
> -	return 0;
> +	int i, c = 0;
> +
> +	for (i = 0; i < ARRAY_SIZE(lid_init_state_str); i++)
> +		if (i == lid_init_state)
> +			c += sprintf(buf + c, "[%s] ", lid_init_state_str[i]);
> +		else
> +			c += sprintf(buf + c, "%s ", lid_init_state_str[i]);
> +
> +	buf[c - 1] = '\n'; /* Replace the final space with a newline */
> +
> +	return c;
>  }
>  
>  module_param_call(lid_init_state,
> -- 
> 2.23.0
> 

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table
  2019-10-21  9:08   ` Andy Shevchenko
@ 2019-10-24 17:44     ` Hans de Goede
  0 siblings, 0 replies; 8+ messages in thread
From: Hans de Goede @ 2019-10-24 17:44 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Rafael J . Wysocki, Len Brown, Mika Westerberg, linux-acpi

Hi,

On 21-10-2019 11:08, Andy Shevchenko wrote:
> On Fri, Oct 18, 2019 at 09:41:13PM +0200, Hans de Goede wrote:
>> Commit 3540c32a9ae4 ("ACPI / button: Add quirks for initial lid state
>> notification") added 3 different modes to the LID handling code to deal
>> with various buggy implementations.
>>
>> Until now users which need one of the 2 non-default modes to get their
>> hw to work have to pass a kernel commandline option for this.
>>
>> E.g. https://bugzilla.kernel.org/show_bug.cgi?id=106151 was closed with a
>> note that the user has to add "button.lid_init_state=open" to the kernel
>> commandline to get the LID code to not cause undesirable suspends on his
>> Samsung N210 Plus.
>>
>> This commit modifies the existing lid_blacklst dmi table so that it can
>> be used not only to completely disable the LID code on devices where
>> the ACPI tables are broken beyond repair, but also to select one of the 2
>> non default LID handling modes on devices where this is necessary.
>>
>> This will allow us to add quirks to make the LID work OOTB on broken
>> devices. Getting this working OOTB is esp. important because the typical
>> breakage is false LID closed reporting, causing undesirable suspends which
>> basically make the system unusable.
> 
>> +static int lid_init_state = -1;
> 
>>   static int acpi_button_register_driver(struct acpi_driver *driver)
>>   {
>> +	const struct dmi_system_id *dmi_id;
>> +
>> +	if (lid_init_state == -1) {
>> +		dmi_id = dmi_first_match(dmi_lid_quirks);
>> +		if (dmi_id)
> 
>> +			lid_init_state = (long)dmi_id->driver_data;
> 
> I would rather see here (intptr_t), though up to you and Rafael.
> Or mark a variable long itself?

I will make the variable itself long for v2.

>> +		else
>> +			lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
> 
> Can't we simple default the value to this?

No then we do not know if this value was set as module option by
the user, or if it is just the default and we should not use the
dmi based quirks when the value is set by the user, so we must
be able to distinguish the 2 cases.

Regards,

Hans


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-10-24 17:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-18 19:41 [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Hans de Goede
2019-10-18 19:41 ` [PATCH 2/5] ACPI: button: Allow disabling LID support with the lid_init_state module option Hans de Goede
2019-10-18 19:41 ` [PATCH 3/5] ACPI: button: Turn lid_blacklst dmi table into a generic quirk table Hans de Goede
2019-10-21  9:08   ` Andy Shevchenko
2019-10-24 17:44     ` Hans de Goede
2019-10-18 19:41 ` [PATCH 4/5] ACPI: button: Add DMI quirk for Medion Akoya E2215T Hans de Goede
2019-10-18 19:41 ` [PATCH 5/5] ACPI: button: Remove unused acpi_lid_notifier_[un]register functions Hans de Goede
2019-10-21  9:09 ` [PATCH 1/5] ACPI: button: Refactor lid_init_state module parsing code Andy Shevchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.