diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2014-04-14 13:10:17 +0530 |
---|---|---|
committer | Seema Khowala <seemaj@nvidia.com> | 2014-04-23 14:04:25 -0700 |
commit | 4143cd75ae03ec02337d7b33f1ed49e92208f4ab (patch) | |
tree | f4e7d27f254d66e81c93ac64cff455ee9825fb36 /drivers/mfd | |
parent | da5708d284a1ab41a35f0a4dc4afbbc2c90e9be6 (diff) |
mfd: palmas: print wakeup sub-irq on if system wakeup from palams
If system is resumed by the Palmas device then prints the sub-irq of
device which actually cause the wakeup of system.
This helps on finding the submodule which cause system resume.
Change-Id: I8a089baa77fbcd259c8ffeb8825f4de8446df6ed
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/395693
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/palmas.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 66629ef2578c..0609e17e9775 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -28,6 +28,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_platform.h> +#include <linux/system-wakeup.h> #define EXT_PWR_REQ (PALMAS_EXT_CONTROL_ENABLE1 | \ PALMAS_EXT_CONTROL_ENABLE2 | \ @@ -459,6 +460,7 @@ struct palmas_irq_chip_data { int num_mask_regs; int num_edge_regs; int wake_count; + bool wakeup_print_enable; }; static inline const struct palmas_irq *irq_to_palmas_irq( @@ -581,11 +583,27 @@ static const struct irq_chip palmas_irq_chip = { .irq_set_wake = palmas_irq_set_wake, }; +static void print_wakeup_irq(struct device *dev, int irq) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + if (!desc || !desc->action || !desc->action->name) + dev_info(dev, "Device WAKEUP sub-irq %d\n", irq); + else + dev_info(dev, "Device WAKEUP sub-irq %s\n", desc->action->name); +} + static irqreturn_t palmas_irq_thread(int irq, void *data) { struct palmas_irq_chip_data *d = data; int ret, i; bool handled = false; + bool print_wakeup = false; + int sub_irq; + + if (d->wakeup_print_enable && (irq == get_wakeup_reason_irq())) + print_wakeup = true; for (i = 0; i < d->num_mask_regs; i++) { ret = palmas_read(d->palmas, @@ -604,10 +622,14 @@ static irqreturn_t palmas_irq_thread(int irq, void *data) for (i = 0; i < d->num_irqs; i++) { if (d->status_value[d->irqs[i].mask_reg_index] & d->irqs[i].interrupt_mask) { + sub_irq = irq_find_mapping(d->domain, i); + if (print_wakeup) + print_wakeup_irq(d->palmas->dev, sub_irq); handle_nested_irq(irq_find_mapping(d->domain, i)); handled = true; } } + d->wakeup_print_enable = false; if (handled) return IRQ_HANDLED; @@ -1264,6 +1286,22 @@ static int palmas_i2c_remove(struct i2c_client *i2c) return 0; } +static int palmas_i2c_suspend_no_irq(struct device *dev) +{ + struct palmas *palmas = dev_get_drvdata(dev); + + palmas->irq_chip_data->wakeup_print_enable = true; + return 0; +} + +static int palmas_i2c_resume(struct device *dev) +{ + struct palmas *palmas = dev_get_drvdata(dev); + + palmas->irq_chip_data->wakeup_print_enable = false; + return 0; +} + static void palmas_i2c_shutdown(struct i2c_client *i2c) { struct palmas *palmas = i2c_get_clientdata(i2c); @@ -1281,11 +1319,17 @@ static const struct i2c_device_id palmas_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); +static const struct dev_pm_ops palams_pm_ops = { + .suspend_noirq = palmas_i2c_suspend_no_irq, + .resume = palmas_i2c_resume, +}; + static struct i2c_driver palmas_i2c_driver = { .driver = { .name = "palmas", .of_match_table = of_palmas_match_tbl, .owner = THIS_MODULE, + .pm = &palams_pm_ops, }, .probe = palmas_i2c_probe, .remove = palmas_i2c_remove, |