diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-04-01 08:00:06 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2015-04-02 19:14:52 -0400 |
commit | 6f46aedb9c85873b67f6186a8b0f9d7a769b6b2c (patch) | |
tree | 376bc96b0c0ceaaa6c12ef676105612dbf6a3e0b | |
parent | 5593ce64d875d169a237e3818a4251948c901ce7 (diff) |
irqchip: renesas-irqc: Add wake-up support
The IRQC module clock is managed through Runtime PM and PM Domains.
If wake-up is enabled, this clock must not be disabled during system
suspend.
Hence implement irq_chip.irq_set_wake(), which increments/decrements the
clock's enable_count when needed.
This fixes wake-up by gpio-keys on r8a73a4/ape6evm.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Link: https://lkml.kernel.org/r/1427889606-18671-1-git-send-email-geert+renesas@glider.be
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | drivers/irqchip/irq-renesas-irqc.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 2fe9612041b0..7be2fdf69924 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/clk.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
@@ -66,6 +67,7 @@ struct irqc_priv { | |||
66 | struct platform_device *pdev; | 67 | struct platform_device *pdev; |
67 | struct irq_chip irq_chip; | 68 | struct irq_chip irq_chip; |
68 | struct irq_domain *irq_domain; | 69 | struct irq_domain *irq_domain; |
70 | struct clk *clk; | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | static void irqc_dbg(struct irqc_irq *i, char *str) | 73 | static void irqc_dbg(struct irqc_irq *i, char *str) |
@@ -119,6 +121,21 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type) | |||
119 | return 0; | 121 | return 0; |
120 | } | 122 | } |
121 | 123 | ||
124 | static int irqc_irq_set_wake(struct irq_data *d, unsigned int on) | ||
125 | { | ||
126 | struct irqc_priv *p = irq_data_get_irq_chip_data(d); | ||
127 | |||
128 | if (!p->clk) | ||
129 | return 0; | ||
130 | |||
131 | if (on) | ||
132 | clk_enable(p->clk); | ||
133 | else | ||
134 | clk_disable(p->clk); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
122 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) | 139 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) |
123 | { | 140 | { |
124 | struct irqc_irq *i = dev_id; | 141 | struct irqc_irq *i = dev_id; |
@@ -181,6 +198,12 @@ static int irqc_probe(struct platform_device *pdev) | |||
181 | p->pdev = pdev; | 198 | p->pdev = pdev; |
182 | platform_set_drvdata(pdev, p); | 199 | platform_set_drvdata(pdev, p); |
183 | 200 | ||
201 | p->clk = devm_clk_get(&pdev->dev, NULL); | ||
202 | if (IS_ERR(p->clk)) { | ||
203 | dev_warn(&pdev->dev, "unable to get clock\n"); | ||
204 | p->clk = NULL; | ||
205 | } | ||
206 | |||
184 | pm_runtime_enable(&pdev->dev); | 207 | pm_runtime_enable(&pdev->dev); |
185 | pm_runtime_get_sync(&pdev->dev); | 208 | pm_runtime_get_sync(&pdev->dev); |
186 | 209 | ||
@@ -224,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev) | |||
224 | irq_chip->irq_mask = irqc_irq_disable; | 247 | irq_chip->irq_mask = irqc_irq_disable; |
225 | irq_chip->irq_unmask = irqc_irq_enable; | 248 | irq_chip->irq_unmask = irqc_irq_enable; |
226 | irq_chip->irq_set_type = irqc_irq_set_type; | 249 | irq_chip->irq_set_type = irqc_irq_set_type; |
227 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; | 250 | irq_chip->irq_set_wake = irqc_irq_set_wake; |
251 | irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; | ||
228 | 252 | ||
229 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 253 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, |
230 | p->number_of_irqs, | 254 | p->number_of_irqs, |