Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: mt6397: Implement wake handler and suspend/resume to handle wake up event

Implement .irq_set_wake() to get who is wakeup source and setup on suspend/reumse. Enable
mt6393_irq as wake up source properly to pinctrl by enable_irq_wake()/enable_irq_wake().

Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Henry Chen and committed by
Lee Jones
f3151ab4 d9c93f5d

+50
+49
drivers/mfd/mt6397-core.c
··· 93 93 mt6397->irq_masks_cur[reg] |= BIT(shift); 94 94 } 95 95 96 + #ifdef CONFIG_PM_SLEEP 97 + static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on) 98 + { 99 + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data); 100 + int shift = irq_data->hwirq & 0xf; 101 + int reg = irq_data->hwirq >> 4; 102 + 103 + if (on) 104 + mt6397->wake_mask[reg] |= BIT(shift); 105 + else 106 + mt6397->wake_mask[reg] &= ~BIT(shift); 107 + 108 + return 0; 109 + } 110 + #else 111 + #define mt6397_irq_set_wake NULL 112 + #endif 113 + 96 114 static struct irq_chip mt6397_irq_chip = { 97 115 .name = "mt6397-irq", 98 116 .irq_bus_lock = mt6397_irq_lock, 99 117 .irq_bus_sync_unlock = mt6397_irq_sync_unlock, 100 118 .irq_enable = mt6397_irq_enable, 101 119 .irq_disable = mt6397_irq_disable, 120 + .irq_set_wake = mt6397_irq_set_wake, 102 121 }; 103 122 104 123 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, ··· 198 179 return 0; 199 180 } 200 181 182 + #ifdef CONFIG_PM_SLEEP 183 + static int mt6397_irq_suspend(struct device *dev) 184 + { 185 + struct mt6397_chip *chip = dev_get_drvdata(dev); 186 + 187 + regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]); 188 + regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]); 189 + 190 + enable_irq_wake(chip->irq); 191 + 192 + return 0; 193 + } 194 + 195 + static int mt6397_irq_resume(struct device *dev) 196 + { 197 + struct mt6397_chip *chip = dev_get_drvdata(dev); 198 + 199 + regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]); 200 + regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]); 201 + 202 + disable_irq_wake(chip->irq); 203 + 204 + return 0; 205 + } 206 + #endif 207 + 208 + static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend, 209 + mt6397_irq_resume); 210 + 201 211 static int mt6397_probe(struct platform_device *pdev) 202 212 { 203 213 int ret; ··· 281 233 .driver = { 282 234 .name = "mt6397", 283 235 .of_match_table = of_match_ptr(mt6397_of_match), 236 + .pm = &mt6397_pm_ops, 284 237 }, 285 238 }; 286 239
+1
include/linux/mfd/mt6397/core.h
··· 57 57 int irq; 58 58 struct irq_domain *irq_domain; 59 59 struct mutex irqlock; 60 + u16 wake_mask[2]; 60 61 u16 irq_masks_cur[2]; 61 62 u16 irq_masks_cache[2]; 62 63 };