Re: [PATCHv2] i2c: omap: Use noirq system sleep pm ops to idle device for suspend

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

 



* Andreas Kemnade <andreas@xxxxxxxxxxxx> [190222 20:08]:
> Some more research:
> what failed is this:
> static int
> omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> {
>         struct omap_i2c_dev *omap = i2c_get_adapdata(adap);
>         int i;
>         int r;
> 
>         r = pm_runtime_get_sync(omap->dev);
>         if (r < 0) {
> we get -EACCESS there.

OK

> It is indeed the case that 
> handle_twl4030_pih is called before i2c runtime resume.
> Since we have threaded irq here, we can do some sleep in case of
> problems. So this dirty hack helps:
> 
> diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
> index b16c16f194fd..6c729c4ec9b0 100644
> --- a/drivers/mfd/twl4030-irq.c
> +++ b/drivers/mfd/twl4030-irq.c
> @@ -34,6 +34,7 @@
>  #include <linux/of.h>
>  #include <linux/irqdomain.h>
>  #include <linux/mfd/twl.h>
> +#include <linux/delay.h>
>  
>  #include "twl-core.h"
>  
> @@ -298,7 +299,11 @@ static irqreturn_t handle_twl4030_pih(int irq, void *devid)
>                               REG_PIH_ISR_P1);
>         if (ret) {
>                 pr_warn("twl4030: I2C error %d reading PIH ISR\n", ret);
> -               return IRQ_NONE;
> +               msleep(10);
> +               ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr,
> +                                     REG_PIH_ISR_P1);
> +               if (ret)
> +                       return IRQ_NONE;
>         }
>  
>         while (pih_isr) {

How about just check for -EACCESS and return IRQ_NONE without
warning here? And only warn for other errors.

Then in Linux next, we now have new i2c_mark_adapter_suspended(),
so later on if we have something like is_i2c_adapter_suspended()
that could be added. But that's not going to be available for
v5.0 kernels, so for the fix I'd go with just -EACCES + IRQ_NONE.

> So if for some reason handle_twl4030_pih is called late enough, we will
> not have those problems.
> So maybe we just need to add a suspend/resume callback pair in
> twl-core.c and disable/enable the pih there? So when the pih is run,
> runtime_pm is ready, so you are allowed to do pm_runtime_get()
> 
> To wake up from suspend, it is sufficient to have
> 
>         twl4030_pins: pinmux_twl4030_pins {
>                 pinctrl-single,pins = <
>                         OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
>                 >;
>         };

Well PIN_OFF_WAKEUPENABLE is nowadays managed with Linux generic
wakeirqs with dev_pm_set_dedicated_wake_irq(). But in this case
you should not even need to set a pad wake up as i2c1 is in
always-on domain.

Because of the RTC on twl, it's best to not add new dependencies
pin muxing and generic wakeirqs that might be needed if we mask
the twl interrupt for suspend.

Regards,

Tony





[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux