aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/irq.h54
-rw-r--r--include/linux/irqdesc.h3
-rw-r--r--kernel/irq/internals.h10
-rw-r--r--kernel/irq/irqdesc.c1
-rw-r--r--kernel/irq/irqdomain.c1
5 files changed, 41 insertions, 28 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 48cb7d1aa58f..3c7fbe44edae 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -126,13 +126,21 @@ struct msi_desc;
126struct irq_domain; 126struct irq_domain;
127 127
128/** 128/**
129 * struct irq_data - per irq and irq chip data passed down to chip functions 129 * struct irq_common_data - per irq data shared by all irqchips
130 * @state_use_accessors: status information for irq chip functions.
131 * Use accessor functions to deal with it
132 */
133struct irq_common_data {
134 unsigned int state_use_accessors;
135};
136
137/**
138 * struct irq_data - per irq chip data passed down to chip functions
130 * @mask: precomputed bitmask for accessing the chip registers 139 * @mask: precomputed bitmask for accessing the chip registers
131 * @irq: interrupt number 140 * @irq: interrupt number
132 * @hwirq: hardware interrupt number, local to the interrupt domain 141 * @hwirq: hardware interrupt number, local to the interrupt domain
133 * @node: node index useful for balancing 142 * @node: node index useful for balancing
134 * @state_use_accessors: status information for irq chip functions. 143 * @common: point to data shared by all irqchips
135 * Use accessor functions to deal with it
136 * @chip: low level interrupt hardware access 144 * @chip: low level interrupt hardware access
137 * @domain: Interrupt translation domain; responsible for mapping 145 * @domain: Interrupt translation domain; responsible for mapping
138 * between hwirq number and linux irq number. 146 * between hwirq number and linux irq number.
@@ -153,7 +161,7 @@ struct irq_data {
153 unsigned int irq; 161 unsigned int irq;
154 unsigned long hwirq; 162 unsigned long hwirq;
155 unsigned int node; 163 unsigned int node;
156 unsigned int state_use_accessors; 164 struct irq_common_data *common;
157 struct irq_chip *chip; 165 struct irq_chip *chip;
158 struct irq_domain *domain; 166 struct irq_domain *domain;
159#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY 167#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -166,7 +174,7 @@ struct irq_data {
166}; 174};
167 175
168/* 176/*
169 * Bit masks for irq_data.state 177 * Bit masks for irq_common_data.state_use_accessors
170 * 178 *
171 * IRQD_TRIGGER_MASK - Mask for the trigger type bits 179 * IRQD_TRIGGER_MASK - Mask for the trigger type bits
172 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending 180 * IRQD_SETAFFINITY_PENDING - Affinity setting is pending
@@ -198,34 +206,36 @@ enum {
198 IRQD_WAKEUP_ARMED = (1 << 19), 206 IRQD_WAKEUP_ARMED = (1 << 19),
199}; 207};
200 208
209#define __irqd_to_state(d) ((d)->common->state_use_accessors)
210
201static inline bool irqd_is_setaffinity_pending(struct irq_data *d) 211static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
202{ 212{
203 return d->state_use_accessors & IRQD_SETAFFINITY_PENDING; 213 return __irqd_to_state(d) & IRQD_SETAFFINITY_PENDING;
204} 214}
205 215
206static inline bool irqd_is_per_cpu(struct irq_data *d) 216static inline bool irqd_is_per_cpu(struct irq_data *d)
207{ 217{
208 return d->state_use_accessors & IRQD_PER_CPU; 218 return __irqd_to_state(d) & IRQD_PER_CPU;
209} 219}
210 220
211static inline bool irqd_can_balance(struct irq_data *d) 221static inline bool irqd_can_balance(struct irq_data *d)
212{ 222{
213 return !(d->state_use_accessors & (IRQD_PER_CPU | IRQD_NO_BALANCING)); 223 return !(__irqd_to_state(d) & (IRQD_PER_CPU | IRQD_NO_BALANCING));
214} 224}
215 225
216static inline bool irqd_affinity_was_set(struct irq_data *d) 226static inline bool irqd_affinity_was_set(struct irq_data *d)
217{ 227{
218 return d->state_use_accessors & IRQD_AFFINITY_SET; 228 return __irqd_to_state(d) & IRQD_AFFINITY_SET;
219} 229}
220 230
221static inline void irqd_mark_affinity_was_set(struct irq_data *d) 231static inline void irqd_mark_affinity_was_set(struct irq_data *d)
222{ 232{
223 d->state_use_accessors |= IRQD_AFFINITY_SET; 233 __irqd_to_state(d) |= IRQD_AFFINITY_SET;
224} 234}
225 235
226static inline u32 irqd_get_trigger_type(struct irq_data *d) 236static inline u32 irqd_get_trigger_type(struct irq_data *d)
227{ 237{
228 return d->state_use_accessors & IRQD_TRIGGER_MASK; 238 return __irqd_to_state(d) & IRQD_TRIGGER_MASK;
229} 239}
230 240
231/* 241/*
@@ -233,43 +243,43 @@ static inline u32 irqd_get_trigger_type(struct irq_data *d)
233 */ 243 */
234static inline void irqd_set_trigger_type(struct irq_data *d, u32 type) 244static inline void irqd_set_trigger_type(struct irq_data *d, u32 type)
235{ 245{
236 d->state_use_accessors &= ~IRQD_TRIGGER_MASK; 246 __irqd_to_state(d) &= ~IRQD_TRIGGER_MASK;
237 d->state_use_accessors |= type & IRQD_TRIGGER_MASK; 247 __irqd_to_state(d) |= type & IRQD_TRIGGER_MASK;
238} 248}
239 249
240static inline bool irqd_is_level_type(struct irq_data *d) 250static inline bool irqd_is_level_type(struct irq_data *d)
241{ 251{
242 return d->state_use_accessors & IRQD_LEVEL; 252 return __irqd_to_state(d) & IRQD_LEVEL;
243} 253}
244 254
245static inline bool irqd_is_wakeup_set(struct irq_data *d) 255static inline bool irqd_is_wakeup_set(struct irq_data *d)
246{ 256{
247 return d->state_use_accessors & IRQD_WAKEUP_STATE; 257 return __irqd_to_state(d) & IRQD_WAKEUP_STATE;
248} 258}
249 259
250static inline bool irqd_can_move_in_process_context(struct irq_data *d) 260static inline bool irqd_can_move_in_process_context(struct irq_data *d)
251{ 261{
252 return d->state_use_accessors & IRQD_MOVE_PCNTXT; 262 return __irqd_to_state(d) & IRQD_MOVE_PCNTXT;
253} 263}
254 264
255static inline bool irqd_irq_disabled(struct irq_data *d) 265static inline bool irqd_irq_disabled(struct irq_data *d)
256{ 266{
257 return d->state_use_accessors & IRQD_IRQ_DISABLED; 267 return __irqd_to_state(d) & IRQD_IRQ_DISABLED;
258} 268}
259 269
260static inline bool irqd_irq_masked(struct irq_data *d) 270static inline bool irqd_irq_masked(struct irq_data *d)
261{ 271{
262 return d->state_use_accessors & IRQD_IRQ_MASKED; 272 return __irqd_to_state(d) & IRQD_IRQ_MASKED;
263} 273}
264 274
265static inline bool irqd_irq_inprogress(struct irq_data *d) 275static inline bool irqd_irq_inprogress(struct irq_data *d)
266{ 276{
267 return d->state_use_accessors & IRQD_IRQ_INPROGRESS; 277 return __irqd_to_state(d) & IRQD_IRQ_INPROGRESS;
268} 278}
269 279
270static inline bool irqd_is_wakeup_armed(struct irq_data *d) 280static inline bool irqd_is_wakeup_armed(struct irq_data *d)
271{ 281{
272 return d->state_use_accessors & IRQD_WAKEUP_ARMED; 282 return __irqd_to_state(d) & IRQD_WAKEUP_ARMED;
273} 283}
274 284
275 285
@@ -280,12 +290,12 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d)
280 */ 290 */
281static inline void irqd_set_chained_irq_inprogress(struct irq_data *d) 291static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
282{ 292{
283 d->state_use_accessors |= IRQD_IRQ_INPROGRESS; 293 __irqd_to_state(d) |= IRQD_IRQ_INPROGRESS;
284} 294}
285 295
286static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) 296static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
287{ 297{
288 d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; 298 __irqd_to_state(d) &= ~IRQD_IRQ_INPROGRESS;
289} 299}
290 300
291static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 301static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index a113a8dc7438..c52d1480f272 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,7 +17,7 @@ struct pt_regs;
17 17
18/** 18/**
19 * struct irq_desc - interrupt descriptor 19 * struct irq_desc - interrupt descriptor
20 * @irq_data: per irq and chip data passed down to chip functions 20 * @irq_common_data: per irq and chip data passed down to chip functions
21 * @kstat_irqs: irq stats per cpu 21 * @kstat_irqs: irq stats per cpu
22 * @handle_irq: highlevel irq-events handler 22 * @handle_irq: highlevel irq-events handler
23 * @preflow_handler: handler called before the flow handler (currently used by sparc) 23 * @preflow_handler: handler called before the flow handler (currently used by sparc)
@@ -47,6 +47,7 @@ struct pt_regs;
47 * @name: flow handler name for /proc/interrupts output 47 * @name: flow handler name for /proc/interrupts output
48 */ 48 */
49struct irq_desc { 49struct irq_desc {
50 struct irq_common_data irq_common_data;
50 struct irq_data irq_data; 51 struct irq_data irq_data;
51 unsigned int __percpu *kstat_irqs; 52 unsigned int __percpu *kstat_irqs;
52 irq_flow_handler_t handle_irq; 53 irq_flow_handler_t handle_irq;
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b93d434e70bd..a1ed80d11800 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -168,27 +168,27 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
168 */ 168 */
169static inline void irqd_set_move_pending(struct irq_data *d) 169static inline void irqd_set_move_pending(struct irq_data *d)
170{ 170{
171 d->state_use_accessors |= IRQD_SETAFFINITY_PENDING; 171 __irqd_to_state(d) |= IRQD_SETAFFINITY_PENDING;
172} 172}
173 173
174static inline void irqd_clr_move_pending(struct irq_data *d) 174static inline void irqd_clr_move_pending(struct irq_data *d)
175{ 175{
176 d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING; 176 __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
177} 177}
178 178
179static inline void irqd_clear(struct irq_data *d, unsigned int mask) 179static inline void irqd_clear(struct irq_data *d, unsigned int mask)
180{ 180{
181 d->state_use_accessors &= ~mask; 181 __irqd_to_state(d) &= ~mask;
182} 182}
183 183
184static inline void irqd_set(struct irq_data *d, unsigned int mask) 184static inline void irqd_set(struct irq_data *d, unsigned int mask)
185{ 185{
186 d->state_use_accessors |= mask; 186 __irqd_to_state(d) |= mask;
187} 187}
188 188
189static inline bool irqd_has_set(struct irq_data *d, unsigned int mask) 189static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
190{ 190{
191 return d->state_use_accessors & mask; 191 return __irqd_to_state(d) & mask;
192} 192}
193 193
194static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc) 194static inline void kstat_incr_irqs_this_cpu(unsigned int irq, struct irq_desc *desc)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 99793b9b6d23..eac1aac906ea 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -76,6 +76,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
76{ 76{
77 int cpu; 77 int cpu;
78 78
79 desc->irq_data.common = &desc->irq_common_data;
79 desc->irq_data.irq = irq; 80 desc->irq_data.irq = irq;
80 desc->irq_data.chip = &no_irq_chip; 81 desc->irq_data.chip = &no_irq_chip;
81 desc->irq_data.chip_data = NULL; 82 desc->irq_data.chip_data = NULL;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7fac311057b8..3552b8750efd 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -834,6 +834,7 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
834 if (irq_data) { 834 if (irq_data) {
835 child->parent_data = irq_data; 835 child->parent_data = irq_data;
836 irq_data->irq = child->irq; 836 irq_data->irq = child->irq;
837 irq_data->common = child->common;
837 irq_data->node = child->node; 838 irq_data->node = child->node;
838 irq_data->domain = domain; 839 irq_data->domain = domain;
839 } 840 }