diff options
author | Sudeep Holla <sudeep.holla@arm.com> | 2015-06-05 06:59:57 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-06-05 16:26:33 -0400 |
commit | 55963c9f20d03124eefb4c365e1ca1f485fc3974 (patch) | |
tree | 862b19e8115dc6cbec2176e33668c40acf246cc6 | |
parent | 496c28b13eb9d4f9c751b672daad8b110084cfd8 (diff) |
irqchip: gic: Simplify gic_configure_irq by using IRQCHIP_SET_TYPE_MASKED
GIC requires to disable the interrupt before changing the trigger type.
irqchip core provides IRQCHIP_SET_TYPE_MASKED flag and ensures that the
interrupt is masked before calling chip.irq_set_type() if the irqchip
sets the flag.
This patch adds IRQCHIP_SET_TYPE_MASKED to GIC irqchip so that the core
can manage disabling the interrupt while changing the trigger type.
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: http://lkml.kernel.org/r/1433501997-19205-1-git-send-email-sudeep.holla@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/irqchip/irq-gic-common.c | 17 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-hip04.c | 1 |
4 files changed, 3 insertions, 17 deletions
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index ad96ebb0c7ab..9448e391cb71 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c | |||
@@ -24,11 +24,8 @@ | |||
24 | int gic_configure_irq(unsigned int irq, unsigned int type, | 24 | int gic_configure_irq(unsigned int irq, unsigned int type, |
25 | void __iomem *base, void (*sync_access)(void)) | 25 | void __iomem *base, void (*sync_access)(void)) |
26 | { | 26 | { |
27 | u32 enablemask = 1 << (irq % 32); | ||
28 | u32 enableoff = (irq / 32) * 4; | ||
29 | u32 confmask = 0x2 << ((irq % 16) * 2); | 27 | u32 confmask = 0x2 << ((irq % 16) * 2); |
30 | u32 confoff = (irq / 16) * 4; | 28 | u32 confoff = (irq / 16) * 4; |
31 | bool enabled = false; | ||
32 | u32 val, oldval; | 29 | u32 val, oldval; |
33 | int ret = 0; | 30 | int ret = 0; |
34 | 31 | ||
@@ -43,17 +40,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type, | |||
43 | val |= confmask; | 40 | val |= confmask; |
44 | 41 | ||
45 | /* | 42 | /* |
46 | * As recommended by the spec, disable the interrupt before changing | ||
47 | * the configuration | ||
48 | */ | ||
49 | if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { | ||
50 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); | ||
51 | if (sync_access) | ||
52 | sync_access(); | ||
53 | enabled = true; | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Write back the new configuration, and possibly re-enable | 43 | * Write back the new configuration, and possibly re-enable |
58 | * the interrupt. If we tried to write a new configuration and failed, | 44 | * the interrupt. If we tried to write a new configuration and failed, |
59 | * return an error. | 45 | * return an error. |
@@ -62,9 +48,6 @@ int gic_configure_irq(unsigned int irq, unsigned int type, | |||
62 | if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval) | 48 | if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval) |
63 | ret = -EINVAL; | 49 | ret = -EINVAL; |
64 | 50 | ||
65 | if (enabled) | ||
66 | writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); | ||
67 | |||
68 | if (sync_access) | 51 | if (sync_access) |
69 | sync_access(); | 52 | sync_access(); |
70 | 53 | ||
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 49875adb6b44..c52f7ba205b4 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -658,6 +658,7 @@ static struct irq_chip gic_chip = { | |||
658 | .irq_set_affinity = gic_set_affinity, | 658 | .irq_set_affinity = gic_set_affinity, |
659 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, | 659 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
660 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, | 660 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
661 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
661 | }; | 662 | }; |
662 | 663 | ||
663 | #define GIC_ID_NR (1U << gic_data.rdists.id_bits) | 664 | #define GIC_ID_NR (1U << gic_data.rdists.id_bits) |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 01999d74bd3a..8d7e1c8b6d56 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -324,6 +324,7 @@ static struct irq_chip gic_chip = { | |||
324 | #endif | 324 | #endif |
325 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, | 325 | .irq_get_irqchip_state = gic_irq_get_irqchip_state, |
326 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, | 326 | .irq_set_irqchip_state = gic_irq_set_irqchip_state, |
327 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
327 | }; | 328 | }; |
328 | 329 | ||
329 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | 330 | void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) |
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 7d6ffb5de84f..0cae45d10695 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c | |||
@@ -202,6 +202,7 @@ static struct irq_chip hip04_irq_chip = { | |||
202 | #ifdef CONFIG_SMP | 202 | #ifdef CONFIG_SMP |
203 | .irq_set_affinity = hip04_irq_set_affinity, | 203 | .irq_set_affinity = hip04_irq_set_affinity, |
204 | #endif | 204 | #endif |
205 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
205 | }; | 206 | }; |
206 | 207 | ||
207 | static u16 hip04_get_cpumask(struct hip04_irq_data *intc) | 208 | static u16 hip04_get_cpumask(struct hip04_irq_data *intc) |