Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
pcmcia
sa1111_generic.c
Go to the documentation of this file.
1
/*
2
* linux/drivers/pcmcia/sa1111_generic.c
3
*
4
* We implement the generic parts of a SA1111 PCMCIA driver. This
5
* basically means we handle everything except controlling the
6
* power. Power is machine specific...
7
*/
8
#include <linux/module.h>
9
#include <linux/kernel.h>
10
#include <
linux/ioport.h
>
11
#include <linux/device.h>
12
#include <
linux/interrupt.h
>
13
#include <
linux/init.h
>
14
#include <
linux/io.h
>
15
#include <linux/slab.h>
16
17
#include <
pcmcia/ss.h
>
18
19
#include <mach/hardware.h>
20
#include <
asm/hardware/sa1111.h
>
21
#include <asm/irq.h>
22
23
#include "
sa1111_generic.h
"
24
25
/*
26
* These are offsets from the above base.
27
*/
28
#define PCCR 0x0000
29
#define PCSSR 0x0004
30
#define PCSR 0x0008
31
32
#define PCSR_S0_READY (1<<0)
33
#define PCSR_S1_READY (1<<1)
34
#define PCSR_S0_DETECT (1<<2)
35
#define PCSR_S1_DETECT (1<<3)
36
#define PCSR_S0_VS1 (1<<4)
37
#define PCSR_S0_VS2 (1<<5)
38
#define PCSR_S1_VS1 (1<<6)
39
#define PCSR_S1_VS2 (1<<7)
40
#define PCSR_S0_WP (1<<8)
41
#define PCSR_S1_WP (1<<9)
42
#define PCSR_S0_BVD1 (1<<10)
43
#define PCSR_S0_BVD2 (1<<11)
44
#define PCSR_S1_BVD1 (1<<12)
45
#define PCSR_S1_BVD2 (1<<13)
46
47
#define PCCR_S0_RST (1<<0)
48
#define PCCR_S1_RST (1<<1)
49
#define PCCR_S0_FLT (1<<2)
50
#define PCCR_S1_FLT (1<<3)
51
#define PCCR_S0_PWAITEN (1<<4)
52
#define PCCR_S1_PWAITEN (1<<5)
53
#define PCCR_S0_PSE (1<<6)
54
#define PCCR_S1_PSE (1<<7)
55
56
#define PCSSR_S0_SLEEP (1<<0)
57
#define PCSSR_S1_SLEEP (1<<1)
58
59
#define IDX_IRQ_S0_READY_NINT (0)
60
#define IDX_IRQ_S0_CD_VALID (1)
61
#define IDX_IRQ_S0_BVD1_STSCHG (2)
62
#define IDX_IRQ_S1_READY_NINT (3)
63
#define IDX_IRQ_S1_CD_VALID (4)
64
#define IDX_IRQ_S1_BVD1_STSCHG (5)
65
66
void
sa1111_pcmcia_socket_state
(
struct
soc_pcmcia_socket
*skt,
struct
pcmcia_state
*
state
)
67
{
68
struct
sa1111_pcmcia_socket
*
s
= to_skt(skt);
69
unsigned
long
status
=
sa1111_readl
(s->
dev
->mapbase +
PCSR
);
70
71
switch
(skt->
nr
) {
72
case
0:
73
state->
detect
= status &
PCSR_S0_DETECT
? 0 : 1;
74
state->
ready
= status &
PCSR_S0_READY
? 1 : 0;
75
state->
bvd1
= status &
PCSR_S0_BVD1
? 1 : 0;
76
state->
bvd2
= status &
PCSR_S0_BVD2
? 1 : 0;
77
state->
wrprot
= status &
PCSR_S0_WP
? 1 : 0;
78
state->
vs_3v
= status &
PCSR_S0_VS1
? 0 : 1;
79
state->
vs_Xv
= status &
PCSR_S0_VS2
? 0 : 1;
80
break
;
81
82
case
1:
83
state->
detect
= status &
PCSR_S1_DETECT
? 0 : 1;
84
state->
ready
= status &
PCSR_S1_READY
? 1 : 0;
85
state->
bvd1
= status &
PCSR_S1_BVD1
? 1 : 0;
86
state->
bvd2
= status &
PCSR_S1_BVD2
? 1 : 0;
87
state->
wrprot
= status &
PCSR_S1_WP
? 1 : 0;
88
state->
vs_3v
= status &
PCSR_S1_VS1
? 0 : 1;
89
state->
vs_Xv
= status &
PCSR_S1_VS2
? 0 : 1;
90
break
;
91
}
92
}
93
94
int
sa1111_pcmcia_configure_socket
(
struct
soc_pcmcia_socket
*skt,
const
socket_state_t
*
state
)
95
{
96
struct
sa1111_pcmcia_socket
*
s
= to_skt(skt);
97
unsigned
int
pccr_skt_mask, pccr_set_mask,
val
;
98
unsigned
long
flags
;
99
100
switch
(skt->
nr
) {
101
case
0:
102
pccr_skt_mask =
PCCR_S0_RST
|
PCCR_S0_FLT
|
PCCR_S0_PWAITEN
|
PCCR_S0_PSE
;
103
break
;
104
105
case
1:
106
pccr_skt_mask =
PCCR_S1_RST
|
PCCR_S1_FLT
|
PCCR_S1_PWAITEN
|
PCCR_S1_PSE
;
107
break
;
108
109
default
:
110
return
-1;
111
}
112
113
pccr_set_mask = 0;
114
115
if
(state->
Vcc
!= 0)
116
pccr_set_mask |=
PCCR_S0_PWAITEN
|
PCCR_S1_PWAITEN
;
117
if
(state->
Vcc
== 50)
118
pccr_set_mask |=
PCCR_S0_PSE
|
PCCR_S1_PSE
;
119
if
(state->
flags
&
SS_RESET
)
120
pccr_set_mask |=
PCCR_S0_RST
|
PCCR_S1_RST
;
121
if
(state->
flags
&
SS_OUTPUT_ENA
)
122
pccr_set_mask |=
PCCR_S0_FLT
|
PCCR_S1_FLT
;
123
124
local_irq_save
(flags);
125
val =
sa1111_readl
(s->
dev
->mapbase +
PCCR
);
126
val &= ~pccr_skt_mask;
127
val |= pccr_set_mask & pccr_skt_mask;
128
sa1111_writel
(val, s->
dev
->mapbase +
PCCR
);
129
local_irq_restore
(flags);
130
131
return
0;
132
}
133
134
int
sa1111_pcmcia_add
(
struct
sa1111_dev
*
dev
,
struct
pcmcia_low_level
*ops,
135
int
(*
add
)(
struct
soc_pcmcia_socket
*))
136
{
137
struct
sa1111_pcmcia_socket
*
s
;
138
int
i
,
ret
= 0;
139
140
ops->
socket_state
=
sa1111_pcmcia_socket_state
;
141
142
for
(i = 0; i < ops->
nr
; i++) {
143
s = kzalloc(
sizeof
(*s),
GFP_KERNEL
);
144
if
(!s)
145
return
-
ENOMEM
;
146
147
s->
soc
.nr = ops->
first
+
i
;
148
soc_pcmcia_init_one
(&s->
soc
, ops, &dev->
dev
);
149
s->
dev
=
dev
;
150
if
(s->
soc
.nr) {
151
s->
soc
.socket.pci_irq = dev->
irq
[
IDX_IRQ_S1_READY_NINT
];
152
s->
soc
.stat[
SOC_STAT_CD
].irq = dev->
irq
[
IDX_IRQ_S1_CD_VALID
];
153
s->
soc
.stat[
SOC_STAT_CD
].name =
"SA1111 CF card detect"
;
154
s->
soc
.stat[
SOC_STAT_BVD1
].irq = dev->
irq
[
IDX_IRQ_S1_BVD1_STSCHG
];
155
s->
soc
.stat[
SOC_STAT_BVD1
].name =
"SA1111 CF BVD1"
;
156
}
else
{
157
s->
soc
.socket.pci_irq = dev->
irq
[
IDX_IRQ_S0_READY_NINT
];
158
s->
soc
.stat[
SOC_STAT_CD
].irq = dev->
irq
[
IDX_IRQ_S0_CD_VALID
];
159
s->
soc
.stat[
SOC_STAT_CD
].name =
"SA1111 PCMCIA card detect"
;
160
s->
soc
.stat[
SOC_STAT_BVD1
].irq = dev->
irq
[
IDX_IRQ_S0_BVD1_STSCHG
];
161
s->
soc
.stat[
SOC_STAT_BVD1
].name =
"SA1111 PCMCIA BVD1"
;
162
}
163
164
ret =
add
(&s->
soc
);
165
if
(ret == 0) {
166
s->
next
=
dev_get_drvdata
(&dev->
dev
);
167
dev_set_drvdata
(&dev->
dev
, s);
168
}
else
169
kfree
(s);
170
}
171
172
return
ret
;
173
}
174
175
static
int
pcmcia_probe(
struct
sa1111_dev
*dev)
176
{
177
void
__iomem
*
base
;
178
int
ret
;
179
180
ret =
sa1111_enable_device
(dev);
181
if
(ret)
182
return
ret
;
183
184
dev_set_drvdata
(&dev->
dev
,
NULL
);
185
186
if
(!
request_mem_region
(dev->
res
.start, 512,
SA1111_DRIVER_NAME
(dev))) {
187
sa1111_disable_device
(dev);
188
return
-
EBUSY
;
189
}
190
191
base = dev->
mapbase
;
192
193
/*
194
* Initialise the suspend state.
195
*/
196
sa1111_writel
(
PCSSR_S0_SLEEP
|
PCSSR_S1_SLEEP
, base +
PCSSR
);
197
sa1111_writel
(
PCCR_S0_FLT
|
PCCR_S1_FLT
, base +
PCCR
);
198
199
#ifdef CONFIG_SA1100_BADGE4
200
pcmcia_badge4_init
(&dev->
dev
);
201
#endif
202
#ifdef CONFIG_SA1100_JORNADA720
203
pcmcia_jornada720_init
(&dev->
dev
);
204
#endif
205
#ifdef CONFIG_ARCH_LUBBOCK
206
pcmcia_lubbock_init
(dev);
207
#endif
208
#ifdef CONFIG_ASSABET_NEPONSET
209
pcmcia_neponset_init
(dev);
210
#endif
211
return
0;
212
}
213
214
static
int
__devexit
pcmcia_remove(
struct
sa1111_dev
*dev)
215
{
216
struct
sa1111_pcmcia_socket
*
next
, *
s
=
dev_get_drvdata
(&dev->
dev
);
217
218
dev_set_drvdata
(&dev->
dev
,
NULL
);
219
220
for
(;
s
; s =
next
) {
221
next = s->
next
;
222
soc_pcmcia_remove_one
(&s->
soc
);
223
kfree
(s);
224
}
225
226
release_mem_region
(dev->
res
.start, 512);
227
sa1111_disable_device
(dev);
228
return
0;
229
}
230
231
static
struct
sa1111_driver
pcmcia_driver = {
232
.drv = {
233
.name =
"sa1111-pcmcia"
,
234
},
235
.devid =
SA1111_DEVID_PCMCIA
,
236
.probe = pcmcia_probe,
237
.remove =
__devexit_p
(pcmcia_remove),
238
};
239
240
static
int
__init
sa1111_drv_pcmcia_init(
void
)
241
{
242
return
sa1111_driver_register
(&pcmcia_driver);
243
}
244
245
static
void
__exit
sa1111_drv_pcmcia_exit(
void
)
246
{
247
sa1111_driver_unregister
(&pcmcia_driver);
248
}
249
250
fs_initcall
(sa1111_drv_pcmcia_init);
251
module_exit
(sa1111_drv_pcmcia_exit);
252
253
MODULE_DESCRIPTION
(
"SA1111 PCMCIA card socket driver"
);
254
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 14:14:43 for Linux Kernel by
1.8.2