diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 11:38:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 11:38:57 -0500 |
commit | ecb50f0afd35a51ef487e8a54b976052eb03d729 (patch) | |
tree | 27457f87d3dc2ce6c81e16d795f953e66c2fff45 /drivers/irqchip/irq-brcmstb-l2.c | |
parent | a157508c9790ccd1c8b5c6a828d6ba85bbe95aaa (diff) | |
parent | 1655b0530d9502e69686220491ffb15ba0738c58 (diff) |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq core updates from Thomas Gleixner:
"This is the first (boring) part of irq updates:
- support for big endian I/O accessors in the generic irq chip
- cleanup of brcmstb/bcm7120 drivers so they can be reused for non
ARM SoCs
- the usual pile of fixes and updates for the various ARM irq chips"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
irqchip: dw-apb-ictl: Add PM support
irqchip: dw-apb-ictl: Enable IRQ_GC_MASK_CACHE_PER_TYPE
irqchip: dw-apb-ictl: Always use use {readl|writel}_relaxed
ARM: orion: convert the irq_reg_{readl,writel} calls to the new API
irqchip: atmel-aic: Add missing entry for rm9200 irq fixups
irqchip: atmel-aic: Rename at91sam9_aic_irq_fixup for naming consistency
irqchip: atmel-aic: Add specific irq fixup function for sam9g45 and sam9rl
irqchip: atmel-aic: Add irq fixups for at91sam926x SoCs
irqchip: atmel-aic: Add irq fixup for RTT block
irqchip: brcmstb-l2: Convert driver to use irq_reg_{readl,writel}
irqchip: bcm7120-l2: Convert driver to use irq_reg_{readl,writel}
irqchip: bcm7120-l2: Decouple driver from brcmstb-l2
irqchip: bcm7120-l2: Extend driver to support 64+ bit controllers
irqchip: bcm7120-l2: Use gc->mask_cache to simplify suspend/resume functions
irqchip: bcm7120-l2: Fix missing nibble in gc->unused mask
irqchip: bcm7120-l2: Make sure all register accesses use base+offset
irqchip: bcm7120-l2, brcmstb-l2: Remove ARM Kconfig dependency
irqchip: bcm7120-l2: Eliminate bad IRQ check
irqchip: brcmstb-l2: Eliminate dependency on ARM code
genirq: Generic chip: Add big endian I/O accessors
...
Diffstat (limited to 'drivers/irqchip/irq-brcmstb-l2.c')
-rw-r--r-- | drivers/irqchip/irq-brcmstb-l2.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index 14691a4cb84c..313c2c64498a 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c | |||
@@ -18,7 +18,9 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/kconfig.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/spinlock.h> | ||
22 | #include <linux/of.h> | 24 | #include <linux/of.h> |
23 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
24 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
@@ -30,8 +32,6 @@ | |||
30 | #include <linux/irqchip.h> | 32 | #include <linux/irqchip.h> |
31 | #include <linux/irqchip/chained_irq.h> | 33 | #include <linux/irqchip/chained_irq.h> |
32 | 34 | ||
33 | #include <asm/mach/irq.h> | ||
34 | |||
35 | #include "irqchip.h" | 35 | #include "irqchip.h" |
36 | 36 | ||
37 | /* Register offsets in the L2 interrupt controller */ | 37 | /* Register offsets in the L2 interrupt controller */ |
@@ -54,23 +54,26 @@ struct brcmstb_l2_intc_data { | |||
54 | static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) | 54 | static void brcmstb_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc) |
55 | { | 55 | { |
56 | struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); | 56 | struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); |
57 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0); | ||
57 | struct irq_chip *chip = irq_desc_get_chip(desc); | 58 | struct irq_chip *chip = irq_desc_get_chip(desc); |
58 | u32 status; | 59 | u32 status; |
59 | 60 | ||
60 | chained_irq_enter(chip, desc); | 61 | chained_irq_enter(chip, desc); |
61 | 62 | ||
62 | status = __raw_readl(b->base + CPU_STATUS) & | 63 | status = irq_reg_readl(gc, CPU_STATUS) & |
63 | ~(__raw_readl(b->base + CPU_MASK_STATUS)); | 64 | ~(irq_reg_readl(gc, CPU_MASK_STATUS)); |
64 | 65 | ||
65 | if (status == 0) { | 66 | if (status == 0) { |
66 | do_bad_IRQ(irq, desc); | 67 | raw_spin_lock(&desc->lock); |
68 | handle_bad_irq(irq, desc); | ||
69 | raw_spin_unlock(&desc->lock); | ||
67 | goto out; | 70 | goto out; |
68 | } | 71 | } |
69 | 72 | ||
70 | do { | 73 | do { |
71 | irq = ffs(status) - 1; | 74 | irq = ffs(status) - 1; |
72 | /* ack at our level */ | 75 | /* ack at our level */ |
73 | __raw_writel(1 << irq, b->base + CPU_CLEAR); | 76 | irq_reg_writel(gc, 1 << irq, CPU_CLEAR); |
74 | status &= ~(1 << irq); | 77 | status &= ~(1 << irq); |
75 | generic_handle_irq(irq_find_mapping(b->domain, irq)); | 78 | generic_handle_irq(irq_find_mapping(b->domain, irq)); |
76 | } while (status); | 79 | } while (status); |
@@ -85,12 +88,12 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d) | |||
85 | 88 | ||
86 | irq_gc_lock(gc); | 89 | irq_gc_lock(gc); |
87 | /* Save the current mask */ | 90 | /* Save the current mask */ |
88 | b->saved_mask = __raw_readl(b->base + CPU_MASK_STATUS); | 91 | b->saved_mask = irq_reg_readl(gc, CPU_MASK_STATUS); |
89 | 92 | ||
90 | if (b->can_wake) { | 93 | if (b->can_wake) { |
91 | /* Program the wakeup mask */ | 94 | /* Program the wakeup mask */ |
92 | __raw_writel(~gc->wake_active, b->base + CPU_MASK_SET); | 95 | irq_reg_writel(gc, ~gc->wake_active, CPU_MASK_SET); |
93 | __raw_writel(gc->wake_active, b->base + CPU_MASK_CLEAR); | 96 | irq_reg_writel(gc, gc->wake_active, CPU_MASK_CLEAR); |
94 | } | 97 | } |
95 | irq_gc_unlock(gc); | 98 | irq_gc_unlock(gc); |
96 | } | 99 | } |
@@ -102,11 +105,11 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) | |||
102 | 105 | ||
103 | irq_gc_lock(gc); | 106 | irq_gc_lock(gc); |
104 | /* Clear unmasked non-wakeup interrupts */ | 107 | /* Clear unmasked non-wakeup interrupts */ |
105 | __raw_writel(~b->saved_mask & ~gc->wake_active, b->base + CPU_CLEAR); | 108 | irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active, CPU_CLEAR); |
106 | 109 | ||
107 | /* Restore the saved mask */ | 110 | /* Restore the saved mask */ |
108 | __raw_writel(b->saved_mask, b->base + CPU_MASK_SET); | 111 | irq_reg_writel(gc, b->saved_mask, CPU_MASK_SET); |
109 | __raw_writel(~b->saved_mask, b->base + CPU_MASK_CLEAR); | 112 | irq_reg_writel(gc, ~b->saved_mask, CPU_MASK_CLEAR); |
110 | irq_gc_unlock(gc); | 113 | irq_gc_unlock(gc); |
111 | } | 114 | } |
112 | 115 | ||
@@ -118,6 +121,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
118 | struct irq_chip_generic *gc; | 121 | struct irq_chip_generic *gc; |
119 | struct irq_chip_type *ct; | 122 | struct irq_chip_type *ct; |
120 | int ret; | 123 | int ret; |
124 | unsigned int flags; | ||
121 | 125 | ||
122 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 126 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
123 | if (!data) | 127 | if (!data) |
@@ -131,8 +135,8 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
131 | } | 135 | } |
132 | 136 | ||
133 | /* Disable all interrupts by default */ | 137 | /* Disable all interrupts by default */ |
134 | __raw_writel(0xffffffff, data->base + CPU_MASK_SET); | 138 | writel(0xffffffff, data->base + CPU_MASK_SET); |
135 | __raw_writel(0xffffffff, data->base + CPU_CLEAR); | 139 | writel(0xffffffff, data->base + CPU_CLEAR); |
136 | 140 | ||
137 | data->parent_irq = irq_of_parse_and_map(np, 0); | 141 | data->parent_irq = irq_of_parse_and_map(np, 0); |
138 | if (!data->parent_irq) { | 142 | if (!data->parent_irq) { |
@@ -148,9 +152,16 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np, | |||
148 | goto out_unmap; | 152 | goto out_unmap; |
149 | } | 153 | } |
150 | 154 | ||
155 | /* MIPS chips strapped for BE will automagically configure the | ||
156 | * peripheral registers for CPU-native byte order. | ||
157 | */ | ||
158 | flags = 0; | ||
159 | if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) | ||
160 | flags |= IRQ_GC_BE_IO; | ||
161 | |||
151 | /* Allocate a single Generic IRQ chip for this node */ | 162 | /* Allocate a single Generic IRQ chip for this node */ |
152 | ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, | 163 | ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, |
153 | np->full_name, handle_edge_irq, clr, 0, 0); | 164 | np->full_name, handle_edge_irq, clr, 0, flags); |
154 | if (ret) { | 165 | if (ret) { |
155 | pr_err("failed to allocate generic irq chip\n"); | 166 | pr_err("failed to allocate generic irq chip\n"); |
156 | goto out_free_domain; | 167 | goto out_free_domain; |