hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* SPDX-License-Identifier: GPL-2.0 */
/*
 *    Copyright IBM Corp. 2002, 2007
 *    Author(s): Ingo Adlung <adlung@de.ibm.com>
 *         Cornelia Huck <cornelia.huck@de.ibm.com>
 *         Arnd Bergmann <arndb@de.ibm.com>
 *         Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
 */
 
#ifndef _ASM_S390_AIRQ_H
#define _ASM_S390_AIRQ_H
 
#include <linux/bit_spinlock.h>
#include <linux/dma-mapping.h>
 
struct airq_struct {
   struct hlist_node list;        /* Handler queueing. */
   void (*handler)(struct airq_struct *airq, bool floating);
   u8 *lsi_ptr;            /* Local-Summary-Indicator pointer */
   u8 lsi_mask;            /* Local-Summary-Indicator mask */
   u8 isc;                /* Interrupt-subclass */
   u8 flags;
};
 
#define AIRQ_PTR_ALLOCATED    0x01
 
int register_adapter_interrupt(struct airq_struct *airq);
void unregister_adapter_interrupt(struct airq_struct *airq);
 
/* Adapter interrupt bit vector */
struct airq_iv {
   unsigned long *vector;    /* Adapter interrupt bit vector */
   dma_addr_t vector_dma; /* Adapter interrupt bit vector dma */
   unsigned long *avail;    /* Allocation bit mask for the bit vector */
   unsigned long *bitlock;    /* Lock bit mask for the bit vector */
   unsigned long *ptr;    /* Pointer associated with each bit */
   unsigned int *data;    /* 32 bit value associated with each bit */
   unsigned long bits;    /* Number of bits in the vector */
   unsigned long end;    /* Number of highest allocated bit + 1 */
   unsigned long flags;    /* Allocation flags */
   spinlock_t lock;    /* Lock to protect alloc & free */
};
 
#define AIRQ_IV_ALLOC        1    /* Use an allocation bit mask */
#define AIRQ_IV_BITLOCK        2    /* Allocate the lock bit mask */
#define AIRQ_IV_PTR        4    /* Allocate the ptr array */
#define AIRQ_IV_DATA        8    /* Allocate the data array */
#define AIRQ_IV_CACHELINE    16    /* Cacheline alignment for the vector */
 
struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags);
void airq_iv_release(struct airq_iv *iv);
unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num);
void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num);
unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
              unsigned long end);
 
static inline unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
{
   return airq_iv_alloc(iv, 1);
}
 
static inline void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
{
   airq_iv_free(iv, bit, 1);
}
 
static inline unsigned long airq_iv_end(struct airq_iv *iv)
{
   return iv->end;
}
 
static inline void airq_iv_lock(struct airq_iv *iv, unsigned long bit)
{
   const unsigned long be_to_le = BITS_PER_LONG - 1;
   bit_spin_lock(bit ^ be_to_le, iv->bitlock);
}
 
static inline void airq_iv_unlock(struct airq_iv *iv, unsigned long bit)
{
   const unsigned long be_to_le = BITS_PER_LONG - 1;
   bit_spin_unlock(bit ^ be_to_le, iv->bitlock);
}
 
static inline void airq_iv_set_data(struct airq_iv *iv, unsigned long bit,
                   unsigned int data)
{
   iv->data[bit] = data;
}
 
static inline unsigned int airq_iv_get_data(struct airq_iv *iv,
                       unsigned long bit)
{
   return iv->data[bit];
}
 
static inline void airq_iv_set_ptr(struct airq_iv *iv, unsigned long bit,
                  unsigned long ptr)
{
   iv->ptr[bit] = ptr;
}
 
static inline unsigned long airq_iv_get_ptr(struct airq_iv *iv,
                       unsigned long bit)
{
   return iv->ptr[bit];
}
 
#endif /* _ASM_S390_AIRQ_H */