Re: [PATCH] ACPI / LPSS: Exclude I2C busses shared with PUNIT from pmc_atom_d3_mask

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

 



On Sat, Sep 08, 2018 at 08:08:13PM +0200, Hans de Goede wrote:
> lpss_iosf_enter_d3_state() checks if all hw-blocks using the DMA
> controllers are in d3 before powering down the DMA controllers.
> 
> But on devices, where the I2C bus connected to the PMIC is shared by
> the PUNIT, the controller for that bus will never reach d3 since it has
> an effectively empty _PS3 method. Instead it appears to automatically
> power-down during S0i3 and we never see it as being in d3.
> 
> This causes the DMA controllers to never be powered-down on these devices,
> causing them to never reach S0i3. This commit uses the ACPI _SEM method
> to detect if an I2C bus is shared with the PUNIT and if it is, it removes
> it from the mask of devices which lpss_iosf_enter_d3_state() checks for.
> 
> This fixes these devices never reaching any S0ix states.
> 
> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
> ---
>  drivers/acpi/acpi_lpss.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
> index 969bf8d515c0..83875305b1d4 100644
> --- a/drivers/acpi/acpi_lpss.c
> +++ b/drivers/acpi/acpi_lpss.c
> @@ -99,6 +99,9 @@ struct lpss_private_data {
>  	u32 prv_reg_ctx[LPSS_PRV_REG_COUNT];
>  };
>  
> +/* Devices which need to be in D3 before lpss_iosf_enter_d3_state() proceeds */
> +static u32 pmc_atom_d3_mask = 0xfe000ffe;
> +
>  /* LPSS run time quirks */
>  static unsigned int lpss_quirks;
>  
> @@ -175,6 +178,21 @@ static void byt_pwm_setup(struct lpss_private_data *pdata)
>  
>  static void byt_i2c_setup(struct lpss_private_data *pdata)
>  {
> +	const char *uid_str = acpi_device_uid(pdata->adev);
> +	acpi_handle handle = pdata->adev->handle;
> +	unsigned long long shared_host = 0;
> +	acpi_status status;
> +	long uid = 0;

Hmm, I wonder if uid=0 is actually valid? IIRC they start from 0 and go
forward from that.

> +
> +	/* Expected to always be true, but better safe then sorry */
> +	if (uid_str)
> +		uid = simple_strtol(uid_str, NULL, 10);
> +
> +	/* Detect I2C bus shared with PUNIT and ignore its d3 status */
> +	status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
> +	if (ACPI_SUCCESS(status) && shared_host && uid)
> +		pmc_atom_d3_mask &= ~(BIT_LPSS2_F1_I2C1 << (uid - 1));



[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