Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/lib/bitops.c
26489 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle ([email protected])
7
* Copyright (c) 1999, 2000 Silicon Graphics, Inc.
8
*/
9
#include <linux/bitops.h>
10
#include <linux/bits.h>
11
#include <linux/irqflags.h>
12
#include <linux/export.h>
13
14
15
/**
16
* __mips_set_bit - Atomically set a bit in memory. This is called by
17
* set_bit() if it cannot find a faster solution.
18
* @nr: the bit to set
19
* @addr: the address to start counting from
20
*/
21
void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
22
{
23
volatile unsigned long *a = &addr[BIT_WORD(nr)];
24
unsigned int bit = nr % BITS_PER_LONG;
25
unsigned long mask;
26
unsigned long flags;
27
28
mask = 1UL << bit;
29
raw_local_irq_save(flags);
30
*a |= mask;
31
raw_local_irq_restore(flags);
32
}
33
EXPORT_SYMBOL(__mips_set_bit);
34
35
36
/**
37
* __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if
38
* it cannot find a faster solution.
39
* @nr: Bit to clear
40
* @addr: Address to start counting from
41
*/
42
void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
43
{
44
volatile unsigned long *a = &addr[BIT_WORD(nr)];
45
unsigned int bit = nr % BITS_PER_LONG;
46
unsigned long mask;
47
unsigned long flags;
48
49
mask = 1UL << bit;
50
raw_local_irq_save(flags);
51
*a &= ~mask;
52
raw_local_irq_restore(flags);
53
}
54
EXPORT_SYMBOL(__mips_clear_bit);
55
56
57
/**
58
* __mips_change_bit - Toggle a bit in memory. This is called by change_bit()
59
* if it cannot find a faster solution.
60
* @nr: Bit to change
61
* @addr: Address to start counting from
62
*/
63
void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
64
{
65
volatile unsigned long *a = &addr[BIT_WORD(nr)];
66
unsigned int bit = nr % BITS_PER_LONG;
67
unsigned long mask;
68
unsigned long flags;
69
70
mask = 1UL << bit;
71
raw_local_irq_save(flags);
72
*a ^= mask;
73
raw_local_irq_restore(flags);
74
}
75
EXPORT_SYMBOL(__mips_change_bit);
76
77
78
/**
79
* __mips_test_and_set_bit_lock - Set a bit and return its old value. This is
80
* called by test_and_set_bit_lock() if it cannot find a faster solution.
81
* @nr: Bit to set
82
* @addr: Address to count from
83
*/
84
int __mips_test_and_set_bit_lock(unsigned long nr,
85
volatile unsigned long *addr)
86
{
87
volatile unsigned long *a = &addr[BIT_WORD(nr)];
88
unsigned int bit = nr % BITS_PER_LONG;
89
unsigned long mask;
90
unsigned long flags;
91
int res;
92
93
mask = 1UL << bit;
94
raw_local_irq_save(flags);
95
res = (mask & *a) != 0;
96
*a |= mask;
97
raw_local_irq_restore(flags);
98
return res;
99
}
100
EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
101
102
103
/**
104
* __mips_test_and_clear_bit - Clear a bit and return its old value. This is
105
* called by test_and_clear_bit() if it cannot find a faster solution.
106
* @nr: Bit to clear
107
* @addr: Address to count from
108
*/
109
int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
110
{
111
volatile unsigned long *a = &addr[BIT_WORD(nr)];
112
unsigned int bit = nr % BITS_PER_LONG;
113
unsigned long mask;
114
unsigned long flags;
115
int res;
116
117
mask = 1UL << bit;
118
raw_local_irq_save(flags);
119
res = (mask & *a) != 0;
120
*a &= ~mask;
121
raw_local_irq_restore(flags);
122
return res;
123
}
124
EXPORT_SYMBOL(__mips_test_and_clear_bit);
125
126
127
/**
128
* __mips_test_and_change_bit - Change a bit and return its old value. This is
129
* called by test_and_change_bit() if it cannot find a faster solution.
130
* @nr: Bit to change
131
* @addr: Address to count from
132
*/
133
int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
134
{
135
volatile unsigned long *a = &addr[BIT_WORD(nr)];
136
unsigned int bit = nr % BITS_PER_LONG;
137
unsigned long mask;
138
unsigned long flags;
139
int res;
140
141
mask = 1UL << bit;
142
raw_local_irq_save(flags);
143
res = (mask & *a) != 0;
144
*a ^= mask;
145
raw_local_irq_restore(flags);
146
return res;
147
}
148
EXPORT_SYMBOL(__mips_test_and_change_bit);
149
150
bool __mips_xor_is_negative_byte(unsigned long mask,
151
volatile unsigned long *addr)
152
{
153
unsigned long flags;
154
unsigned long data;
155
156
raw_local_irq_save(flags);
157
data = *addr;
158
*addr = data ^ mask;
159
raw_local_irq_restore(flags);
160
161
return (data & BIT(7)) != 0;
162
}
163
164