Re: [PATCH] Revert "ACPI / EC: Remove old CLEAR_ON_RESUME quirk"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday, February 1, 2019 7:13:41 AM CET Zhang Rui wrote:
> On some Samsung hardware, it is necessary to clear events accumulated by
> the EC during sleep. These ECs stop reporting GPEs until they are manually
> polled, if too many events are accumulated.
> Thus the CLEAR_ON_RESUME quirk is introduced to send EC query commands
> unconditionally after resume to clear all the EC query events on those
> platforms.
> 
> Later, commit 4c237371f290 ("ACPI / EC: Remove old CLEAR_ON_RESUME quirk")
> removes the CLEAR_ON_RESUME quirk because we thought the new EC IRQ
> polling logic should handle this case.
> 
> Now it has been proved that the EC IRQ Polling logic does not fix the
> issue actually because we got regression report on these Samsung
> platforms after removing the quirk.
> 
> Thus revert commit 4c237371f290 ("ACPI / EC: Remove old CLEAR_ON_RESUME
> quirk") to introduce back the Samsung quirk in this patch.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=44161
> Tested-by: Ortwin Glück <odi@xxxxxx>
> Tested-by: Francisco Cribari <cribari@xxxxxxxxx>
> Tested-by: Balazs Varga <balazs4web@xxxxxxxxx>
> Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx>
> ---
>  drivers/acpi/ec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
> 
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 9d66a47..49e16f0 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -194,6 +194,7 @@ static struct workqueue_struct *ec_query_wq;
>  static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
>  static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
>  static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
> +static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
>  
>  /* --------------------------------------------------------------------------
>   *                           Logging/Debugging
> @@ -499,6 +500,26 @@ static inline void __acpi_ec_disable_event(struct acpi_ec *ec)
>  		ec_log_drv("event blocked");
>  }
>  
> +/*
> + * Process _Q events that might have accumulated in the EC.
> + * Run with locked ec mutex.
> + */
> +static void acpi_ec_clear(struct acpi_ec *ec)
> +{
> +	int i, status;
> +	u8 value = 0;
> +
> +	for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
> +		status = acpi_ec_query(ec, &value);
> +		if (status || !value)
> +			break;
> +	}
> +	if (unlikely(i == ACPI_EC_CLEAR_MAX))
> +		pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);
> +	else
> +		pr_info("%d stale EC events cleared\n", i);
> +}
> +
>  static void acpi_ec_enable_event(struct acpi_ec *ec)
>  {
>  	unsigned long flags;
> @@ -507,6 +528,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
>  	if (acpi_ec_started(ec))
>  		__acpi_ec_enable_event(ec);
>  	spin_unlock_irqrestore(&ec->lock, flags);
> +
> +	/* Drain additional events if hardware requires that */
> +	if (EC_FLAGS_CLEAR_ON_RESUME)
> +		acpi_ec_clear(ec);
>  }
>  
>  #ifdef CONFIG_PM_SLEEP
> @@ -1821,6 +1846,31 @@ static int ec_flag_query_handshake(const struct dmi_system_id *id)
>  #endif
>  
>  /*
> + * On some hardware it is necessary to clear events accumulated by the EC during
> + * sleep. These ECs stop reporting GPEs until they are manually polled, if too
> + * many events are accumulated. (e.g. Samsung Series 5/9 notebooks)
> + *
> + * https://bugzilla.kernel.org/show_bug.cgi?id=44161
> + *
> + * Ideally, the EC should also be instructed NOT to accumulate events during
> + * sleep (which Windows seems to do somehow), but the interface to control this
> + * behaviour is not known at this time.
> + *
> + * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx,
> + * however it is very likely that other Samsung models are affected.
> + *
> + * On systems which don't accumulate _Q events during sleep, this extra check
> + * should be harmless.
> + */
> +static int ec_clear_on_resume(const struct dmi_system_id *id)
> +{
> +	pr_debug("Detected system needing EC poll on resume.\n");
> +	EC_FLAGS_CLEAR_ON_RESUME = 1;
> +	ec_event_clearing = ACPI_EC_EVT_TIMING_STATUS;
> +	return 0;
> +}
> +
> +/*
>   * Some ECDTs contain wrong register addresses.
>   * MSI MS-171F
>   * https://bugzilla.kernel.org/show_bug.cgi?id=12461
> @@ -1869,6 +1919,9 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
>  	ec_honor_ecdt_gpe, "ASUS X580VD", {
>  	DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
>  	DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
> +	{
> +	ec_clear_on_resume, "Samsung hardware", {
> +	DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
>  	{},
>  };
>  
> 

Applied, thanks!





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux