diff options
author | Jason Cooper <jason@lakedaemon.net> | 2015-04-02 19:27:23 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2015-04-02 19:27:23 -0400 |
commit | 78223354a64284fe1ef74c5a7900435776fcf2a0 (patch) | |
tree | 857ca5c95f2908cea04fc8ecb35959921cec1a0d /drivers/irqchip | |
parent | 2a6c0f0ad5c0127d18b43674bd94785fae2ef5fe (diff) | |
parent | 6f46aedb9c85873b67f6186a8b0f9d7a769b6b2c (diff) |
Merge branch 'irqchip/renesas' into irqchip/core
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-renesas-irqc.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index 2ea3412fdf8c..cdf80b7794cd 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> |
@@ -29,15 +30,26 @@ | |||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/platform_data/irq-renesas-irqc.h> | 32 | #include <linux/platform_data/irq-renesas-irqc.h> |
33 | #include <linux/pm_runtime.h> | ||
32 | 34 | ||
33 | #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ | 35 | #define IRQC_IRQ_MAX 32 /* maximum 32 interrupts per driver instance */ |
34 | 36 | ||
35 | #define IRQC_REQ_STS 0x00 | 37 | #define IRQC_REQ_STS 0x00 /* Interrupt Request Status Register */ |
36 | #define IRQC_EN_STS 0x04 | 38 | #define IRQC_EN_STS 0x04 /* Interrupt Enable Status Register */ |
37 | #define IRQC_EN_SET 0x08 | 39 | #define IRQC_EN_SET 0x08 /* Interrupt Enable Set Register */ |
38 | #define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) | 40 | #define IRQC_INT_CPU_BASE(n) (0x000 + ((n) * 0x10)) |
39 | #define DETECT_STATUS 0x100 | 41 | /* SYS-CPU vs. RT-CPU */ |
42 | #define DETECT_STATUS 0x100 /* IRQn Detect Status Register */ | ||
43 | #define MONITOR 0x104 /* IRQn Signal Level Monitor Register */ | ||
44 | #define HLVL_STS 0x108 /* IRQn High Level Detect Status Register */ | ||
45 | #define LLVL_STS 0x10c /* IRQn Low Level Detect Status Register */ | ||
46 | #define S_R_EDGE_STS 0x110 /* IRQn Sync Rising Edge Detect Status Reg. */ | ||
47 | #define S_F_EDGE_STS 0x114 /* IRQn Sync Falling Edge Detect Status Reg. */ | ||
48 | #define A_R_EDGE_STS 0x118 /* IRQn Async Rising Edge Detect Status Reg. */ | ||
49 | #define A_F_EDGE_STS 0x11c /* IRQn Async Falling Edge Detect Status Reg. */ | ||
50 | #define CHTEN_STS 0x120 /* Chattering Reduction Status Register */ | ||
40 | #define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) | 51 | #define IRQC_CONFIG(n) (0x180 + ((n) * 0x04)) |
52 | /* IRQn Configuration Register */ | ||
41 | 53 | ||
42 | struct irqc_irq { | 54 | struct irqc_irq { |
43 | int hw_irq; | 55 | int hw_irq; |
@@ -55,6 +67,7 @@ struct irqc_priv { | |||
55 | struct platform_device *pdev; | 67 | struct platform_device *pdev; |
56 | struct irq_chip irq_chip; | 68 | struct irq_chip irq_chip; |
57 | struct irq_domain *irq_domain; | 69 | struct irq_domain *irq_domain; |
70 | struct clk *clk; | ||
58 | }; | 71 | }; |
59 | 72 | ||
60 | static void irqc_dbg(struct irqc_irq *i, char *str) | 73 | static void irqc_dbg(struct irqc_irq *i, char *str) |
@@ -108,6 +121,21 @@ static int irqc_irq_set_type(struct irq_data *d, unsigned int type) | |||
108 | return 0; | 121 | return 0; |
109 | } | 122 | } |
110 | 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 | |||
111 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) | 139 | static irqreturn_t irqc_irq_handler(int irq, void *dev_id) |
112 | { | 140 | { |
113 | struct irqc_irq *i = dev_id; | 141 | struct irqc_irq *i = dev_id; |
@@ -170,6 +198,15 @@ static int irqc_probe(struct platform_device *pdev) | |||
170 | p->pdev = pdev; | 198 | p->pdev = pdev; |
171 | platform_set_drvdata(pdev, p); | 199 | platform_set_drvdata(pdev, p); |
172 | 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 | |||
207 | pm_runtime_enable(&pdev->dev); | ||
208 | pm_runtime_get_sync(&pdev->dev); | ||
209 | |||
173 | /* get hold of manadatory IOMEM */ | 210 | /* get hold of manadatory IOMEM */ |
174 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 211 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
175 | if (!io) { | 212 | if (!io) { |
@@ -210,7 +247,8 @@ static int irqc_probe(struct platform_device *pdev) | |||
210 | irq_chip->irq_mask = irqc_irq_disable; | 247 | irq_chip->irq_mask = irqc_irq_disable; |
211 | irq_chip->irq_unmask = irqc_irq_enable; | 248 | irq_chip->irq_unmask = irqc_irq_enable; |
212 | irq_chip->irq_set_type = irqc_irq_set_type; | 249 | irq_chip->irq_set_type = irqc_irq_set_type; |
213 | 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; | ||
214 | 252 | ||
215 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, | 253 | p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, |
216 | p->number_of_irqs, | 254 | p->number_of_irqs, |
@@ -250,6 +288,8 @@ err3: | |||
250 | err2: | 288 | err2: |
251 | iounmap(p->iomem); | 289 | iounmap(p->iomem); |
252 | err1: | 290 | err1: |
291 | pm_runtime_put(&pdev->dev); | ||
292 | pm_runtime_disable(&pdev->dev); | ||
253 | kfree(p); | 293 | kfree(p); |
254 | err0: | 294 | err0: |
255 | return ret; | 295 | return ret; |
@@ -265,6 +305,8 @@ static int irqc_remove(struct platform_device *pdev) | |||
265 | 305 | ||
266 | irq_domain_remove(p->irq_domain); | 306 | irq_domain_remove(p->irq_domain); |
267 | iounmap(p->iomem); | 307 | iounmap(p->iomem); |
308 | pm_runtime_put(&pdev->dev); | ||
309 | pm_runtime_disable(&pdev->dev); | ||
268 | kfree(p); | 310 | kfree(p); |
269 | return 0; | 311 | return 0; |
270 | } | 312 | } |