hi Sudeep: I test flowlling your blow suggestions,but the system can not be woken. beacuse,mtk_eint_suspend will mask it.As we know if eint wakeup system it must be unmasked before enter suspend flow. e.x static int __maybe_unused elan_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct elan_tp_data *data = i2c_get_clientdata(client); int ret; /* * We are taking the mutex to make sure sysfs operations are * complete before we attempt to bring the device into low[er] * power mode. */ ret = mutex_lock_interruptible(&data->sysfs_mutex); if (ret) return ret; disable_irq(client->irq); if (device_may_wakeup(dev)) { ret = elan_sleep(data); /* Enable wake from IRQ */ data->irq_wake = (enable_irq_wake(client->irq) == 0); } else { ret = elan_disable_power(data); } mutex_unlock(&data->sysfs_mutex); return ret; } thanks Best Regards, Maoguang On Wed, 2015-09-09 at 00:50 +0800, Sudeep Holla wrote: > > On 08/09/15 10:28, Sudeep Holla wrote: > > > > > > On 06/09/15 11:39, maoguang meng wrote: > >> On Wed, 2015-09-02 at 14:02 +0800, Daniel Kurtz wrote: > >>> Hi maoguang, > >>> > >>> On Tue, Aug 25, 2015 at 12:27 AM, Sudeep Holla <sudeep.holla@xxxxxxx> wrote: > >>>> > >>>> > >>>> On 14/08/15 09:38, maoguang.meng@xxxxxxxxxxxx wrote: > >>>>> > >>>>> From: Maoguang Meng <maoguang.meng@xxxxxxxxxxxx> > >>>>> > >>>>> This patch implement irq_set_wake to get who is wakeup source and > >>>>> setup on suspend resume. > >>>>> > >>>>> Signed-off-by: Maoguang Meng <maoguang.meng@xxxxxxxxxxxx> > >>>>> > >>> [snip] > >>> > >>> Can you please respond to Sudeep's questions: > >>> > >>>> Does this pinmux controller: > >>>> > >>>> 1. Support wake-up configuration ? If not, you need to use > >>>> IRQCHIP_SKIP_SET_WAKE. I don't see any value in writing the > >>>> mask_{set,clear} if the same registers are used for {en,dis}able > >> > >> YES. > >> we can call enable_irq_wake(irq) to config this irq as a wake-up > >> source. > >> > > > > No that doesn't answer my question. Yes you can always call > > enable_irq_wake(irq) as along as you have irq_set_wake implemented. > > But my question was does this pinmux controller support wake-up > > configuration. > > > > IMHO, by looking at the implementation I can confirm *NO*, it doesn't. > > So please stop copy-pasting the implementation from other drivers. > > The reason is you operate on the same mask_{set,clear} which you use > > to {en,dis}able the interrupts which means you don't have to do anything > > to configure an interrupt as a wakeup source other than just keeping > > them enabled. Hopefully this clarifies. > > > >>>> > >>>> 2. Is in always on domain ? If not, you need save/restore only to > >>>> resume back the functionality. Generally we can set > >>>> IRQCHIP_MASK_ON_SUSPEND to ensure non-wake-up interrupts are > >>>> disabled during suspend and re-enabled in resume path. You just > >>>> save/restore raw values without tracking the wake-up source. > >> > >> YES. > >> > > > > Again *YES* for what part of my question. If it's always-on, then you > > don't need this suspend/resume callbacks at all, so I assume the answer > > is *NO*. > > > > IIUC this pinmux controller, something like below should work. > > > ---->8 > > From 7c26992bce047efb66a6ba8d2ffec2b272499df7 Mon Sep 17 00:00:00 2001 > From: Sudeep Holla <sudeep.holla@xxxxxxx> > Date: Tue, 8 Sep 2015 17:35:38 +0100 > Subject: [PATCH] pinctrl: mediatek: Enable SKIP_SET_WAKE and MASK_ON_SUSPEND > > The mediatek pinmux controller doesn't provides any facility to configure > the wakeup sources. So instead of providing redundant irq_set_wake > functionality, SKIP_SET_WAKE could be set to it. Also there's no need to > maintain 2 sets of masks. > > This patch enables IRQCHIP_SKIP_SET_WAKE and IRQCHIP_MASK_ON_SUSPEND and > also removes wake_mask. > > Cc: Linus Walleij <linus.walleij@xxxxxxxxxx> > Cc: Matthias Brugger <matthias.bgg@xxxxxxxxx> > Cc: Hongzhou Yang <hongzhou.yang@xxxxxxxxxxxx> > Cc: Yingjoe Chen <yingjoe.chen@xxxxxxxxxxxx> > Cc: Maoguang Meng <maoguang.meng@xxxxxxxxxxxx> > Cc: Chaotian Jing <chaotian.jing@xxxxxxxxxxxx> > Cc: linux-gpio@xxxxxxxxxxxxxxx > Cc: linux-mediatek@xxxxxxxxxxxxxxxxxxx > Signed-off-by: Sudeep Holla <sudeep.holla@xxxxxxx> > --- > drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 24 > +----------------------- > drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 1 - > 2 files changed, 1 insertion(+), 24 deletions(-) > > diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c > b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c > index 7726c6caaf83..d8e194a5bb31 100644 > --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c > +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c > @@ -1063,20 +1063,6 @@ static int mtk_eint_set_type(struct irq_data *d, > return 0; > } > > -static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on) > -{ > - struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d); > - int shift = d->hwirq & 0x1f; > - int reg = d->hwirq >> 5; > - > - if (on) > - pctl->wake_mask[reg] |= BIT(shift); > - else > - pctl->wake_mask[reg] &= ~BIT(shift); > - > - return 0; > -} > - > static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip, > void __iomem *eint_reg_base, u32 *buf) > { > @@ -1112,7 +1098,6 @@ static int mtk_eint_suspend(struct device *device) > > reg = pctl->eint_reg_base; > mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask); > - mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask); > > return 0; > } > @@ -1153,9 +1138,9 @@ static struct irq_chip mtk_pinctrl_irq_chip = { > .irq_unmask = mtk_eint_unmask, > .irq_ack = mtk_eint_ack, > .irq_set_type = mtk_eint_set_type, > - .irq_set_wake = mtk_eint_irq_set_wake, > .irq_request_resources = mtk_pinctrl_irq_request_resources, > .irq_release_resources = mtk_pinctrl_irq_release_resources, > + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, > }; > > static unsigned int mtk_eint_init(struct mtk_pinctrl *pctl) > @@ -1393,13 +1378,6 @@ int mtk_pctrl_init(struct platform_device *pdev, > } > > ports_buf = pctl->devdata->eint_offsets.ports; > - pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf, > - sizeof(*pctl->wake_mask), GFP_KERNEL); > - if (!pctl->wake_mask) { > - ret = -ENOMEM; > - goto chip_error; > - } > - > pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf, > sizeof(*pctl->cur_mask), GFP_KERNEL); > if (!pctl->cur_mask) { > diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h > b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h > index 55a534338931..acd804a945d8 100644 > --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h > +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h > @@ -267,7 +267,6 @@ struct mtk_pinctrl { > void __iomem *eint_reg_base; > struct irq_domain *domain; > int *eint_dual_edges; > - u32 *wake_mask; > u32 *cur_mask; > }; > -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html