diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-06-25 08:17:57 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-22 06:20:02 -0400 |
commit | a9a6f0341df9a634a98aaf252c89962af77d1376 (patch) | |
tree | 92efad15aad3ce29bc86e97720966e06779e6cfb /arch/s390 | |
parent | 0ea46b0e371e3ccc0ce666c4988a7961e4ffa8ec (diff) |
s390/airq: introduce adapter interrupt vector helper
The PCI code is the first user of adapter interrupts vectors.
Add a set of helpers to airq.c to separate the adatper interrupt
code from the PCI bits. The helpers allow for adapter interrupt
vectors of any size.
Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/airq.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/arch/s390/include/asm/airq.h b/arch/s390/include/asm/airq.h index 4066cee0c2d2..4bbb5957ed1b 100644 --- a/arch/s390/include/asm/airq.h +++ b/arch/s390/include/asm/airq.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef _ASM_S390_AIRQ_H | 9 | #ifndef _ASM_S390_AIRQ_H |
10 | #define _ASM_S390_AIRQ_H | 10 | #define _ASM_S390_AIRQ_H |
11 | 11 | ||
12 | #include <linux/bit_spinlock.h> | ||
13 | |||
12 | struct airq_struct { | 14 | struct airq_struct { |
13 | struct hlist_node list; /* Handler queueing. */ | 15 | struct hlist_node list; /* Handler queueing. */ |
14 | void (*handler)(struct airq_struct *); /* Thin-interrupt handler */ | 16 | void (*handler)(struct airq_struct *); /* Thin-interrupt handler */ |
@@ -23,4 +25,69 @@ struct airq_struct { | |||
23 | int register_adapter_interrupt(struct airq_struct *airq); | 25 | int register_adapter_interrupt(struct airq_struct *airq); |
24 | void unregister_adapter_interrupt(struct airq_struct *airq); | 26 | void unregister_adapter_interrupt(struct airq_struct *airq); |
25 | 27 | ||
28 | /* Adapter interrupt bit vector */ | ||
29 | struct airq_iv { | ||
30 | unsigned long *vector; /* Adapter interrupt bit vector */ | ||
31 | unsigned long *avail; /* Allocation bit mask for the bit vector */ | ||
32 | unsigned long *bitlock; /* Lock bit mask for the bit vector */ | ||
33 | unsigned long *ptr; /* Pointer associated with each bit */ | ||
34 | unsigned int *data; /* 32 bit value associated with each bit */ | ||
35 | unsigned long bits; /* Number of bits in the vector */ | ||
36 | unsigned long end; /* Number of highest allocated bit + 1 */ | ||
37 | spinlock_t lock; /* Lock to protect alloc & free */ | ||
38 | }; | ||
39 | |||
40 | #define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */ | ||
41 | #define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */ | ||
42 | #define AIRQ_IV_PTR 4 /* Allocate the ptr array */ | ||
43 | #define AIRQ_IV_DATA 8 /* Allocate the data array */ | ||
44 | |||
45 | struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); | ||
46 | void airq_iv_release(struct airq_iv *iv); | ||
47 | unsigned long airq_iv_alloc_bit(struct airq_iv *iv); | ||
48 | void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit); | ||
49 | unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, | ||
50 | unsigned long end); | ||
51 | |||
52 | static inline unsigned long airq_iv_end(struct airq_iv *iv) | ||
53 | { | ||
54 | return iv->end; | ||
55 | } | ||
56 | |||
57 | static inline void airq_iv_lock(struct airq_iv *iv, unsigned long bit) | ||
58 | { | ||
59 | const unsigned long be_to_le = BITS_PER_LONG - 1; | ||
60 | bit_spin_lock(bit ^ be_to_le, iv->bitlock); | ||
61 | } | ||
62 | |||
63 | static inline void airq_iv_unlock(struct airq_iv *iv, unsigned long bit) | ||
64 | { | ||
65 | const unsigned long be_to_le = BITS_PER_LONG - 1; | ||
66 | bit_spin_unlock(bit ^ be_to_le, iv->bitlock); | ||
67 | } | ||
68 | |||
69 | static inline void airq_iv_set_data(struct airq_iv *iv, unsigned long bit, | ||
70 | unsigned int data) | ||
71 | { | ||
72 | iv->data[bit] = data; | ||
73 | } | ||
74 | |||
75 | static inline unsigned int airq_iv_get_data(struct airq_iv *iv, | ||
76 | unsigned long bit) | ||
77 | { | ||
78 | return iv->data[bit]; | ||
79 | } | ||
80 | |||
81 | static inline void airq_iv_set_ptr(struct airq_iv *iv, unsigned long bit, | ||
82 | unsigned long ptr) | ||
83 | { | ||
84 | iv->ptr[bit] = ptr; | ||
85 | } | ||
86 | |||
87 | static inline unsigned long airq_iv_get_ptr(struct airq_iv *iv, | ||
88 | unsigned long bit) | ||
89 | { | ||
90 | return iv->ptr[bit]; | ||
91 | } | ||
92 | |||
26 | #endif /* _ASM_S390_AIRQ_H */ | 93 | #endif /* _ASM_S390_AIRQ_H */ |