aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2016-06-09 11:13:07 -0400
committerLee Jones <lee.jones@linaro.org>2016-06-29 05:14:38 -0400
commit3df140d11c6dbf319f4e1bc034e202546fc5ec5c (patch)
tree9fe07cd54c75bbd504cef733c1d92e0237569bb0
parentecd98ccefa1bb83865c358d96b98524bc70938a9 (diff)
mfd: max77620: Mask/unmask interrupt before/after servicing it
The programming guidelines of the MAX77620 for servicing interrupt is: 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM. 2. Read IRQTOP and service the interrupt. 3. Once all interrupts has been checked and serviced, the interrupt service routine un-masks the hardware interrupt line by clearing GLBLM. Add the pre and post interrupt service handler for mask and unmask the global interrupt mask bit (for step 1 and 3) as callback from regmap-irq. Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/max77620.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index d4688f3cfe02..4276413a69c6 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = {
111 }, 111 },
112}; 112};
113 113
114static struct regmap_irq_chip max77620_top_irq_chip = {
115 .name = "max77620-top",
116 .irqs = max77620_top_irqs,
117 .num_irqs = ARRAY_SIZE(max77620_top_irqs),
118 .num_regs = 2,
119 .status_base = MAX77620_REG_IRQTOP,
120 .mask_base = MAX77620_REG_IRQTOPM,
121};
122
123static const struct regmap_range max77620_readable_ranges[] = { 114static const struct regmap_range max77620_readable_ranges[] = {
124 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4), 115 regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
125}; 116};
@@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = {
180 .volatile_table = &max77620_volatile_table, 171 .volatile_table = &max77620_volatile_table,
181}; 172};
182 173
174/*
175 * MAX77620 and MAX20024 has the following steps of the interrupt handling
176 * for TOP interrupts:
177 * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
178 * 2. Read IRQTOP and service the interrupt.
179 * 3. Once all interrupts has been checked and serviced, the interrupt service
180 * routine un-masks the hardware interrupt line by clearing GLBLM.
181 */
182static int max77620_irq_global_mask(void *irq_drv_data)
183{
184 struct max77620_chip *chip = irq_drv_data;
185 int ret;
186
187 ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
188 MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
189 if (ret < 0)
190 dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
191
192 return ret;
193}
194
195static int max77620_irq_global_unmask(void *irq_drv_data)
196{
197 struct max77620_chip *chip = irq_drv_data;
198 int ret;
199
200 ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
201 MAX77620_GLBLM_MASK, 0);
202 if (ret < 0)
203 dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
204
205 return ret;
206}
207
208static struct regmap_irq_chip max77620_top_irq_chip = {
209 .name = "max77620-top",
210 .irqs = max77620_top_irqs,
211 .num_irqs = ARRAY_SIZE(max77620_top_irqs),
212 .num_regs = 2,
213 .status_base = MAX77620_REG_IRQTOP,
214 .mask_base = MAX77620_REG_IRQTOPM,
215 .handle_pre_irq = max77620_irq_global_mask,
216 .handle_post_irq = max77620_irq_global_unmask,
217};
218
183/* max77620_get_fps_period_reg_value: Get FPS bit field value from 219/* max77620_get_fps_period_reg_value: Get FPS bit field value from
184 * requested periods. 220 * requested periods.
185 * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560 221 * MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
@@ -431,6 +467,7 @@ static int max77620_probe(struct i2c_client *client,
431 if (ret < 0) 467 if (ret < 0)
432 return ret; 468 return ret;
433 469
470 max77620_top_irq_chip.irq_drv_data = chip;
434 ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, 471 ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
435 IRQF_ONESHOT | IRQF_SHARED, 472 IRQF_ONESHOT | IRQF_SHARED,
436 chip->irq_base, &max77620_top_irq_chip, 473 chip->irq_base, &max77620_top_irq_chip,