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 Mon, Sep 10, 2018 at 02:14:14PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 10-09-18 13:51, Mika Westerberg wrote:
> > 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.
> 
> You are right some devices have 0 based UIDs but not the I2C controllers
> on BYT/CHT those have 1 based UIDs.
> 
> > > +
> > > +	/* 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));
> 
> Hence also the - 1 here.

Ah, missed that :) Thanks for pointing it out.

Acked-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>



[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