diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-11-02 07:53:44 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-07 17:02:05 -0500 |
commit | 3f724080a3e91d76ba6d5cacd3cf0a0cf16d121a (patch) | |
tree | 5e5b5606bd4822b6b8a4a0f1ef87332b7874af47 /drivers/pcmcia | |
parent | 5611cc4572e889b62a7b4c72a413536bf6a9c416 (diff) |
MIPS: Alchemy: remove PB1000 support
Noone seems to have test hardware or care anymore. Drop PB1000 support
and along with it the old Alchemy PCMCIA socket driver.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: linux-mips@linux-mips.org
Cc: netdev@vger.kernel.org
Cc: linux-pcmcia@lists.infradead.org
Patchwork: https://patchwork.linux-mips.org/patch/2881/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/Kconfig | 4 | ||||
-rw-r--r-- | drivers/pcmcia/Makefile | 4 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_generic.c | 545 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_generic.h | 135 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_pb1x00.c | 294 |
5 files changed, 0 insertions, 982 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 6e318ce41136..c022b5cedcf9 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -155,10 +155,6 @@ config PCMCIA_M8XX | |||
155 | 155 | ||
156 | This driver is also available as a module called m8xx_pcmcia. | 156 | This driver is also available as a module called m8xx_pcmcia. |
157 | 157 | ||
158 | config PCMCIA_AU1X00 | ||
159 | tristate "Au1x00 pcmcia support" | ||
160 | depends on MIPS_ALCHEMY && PCMCIA | ||
161 | |||
162 | config PCMCIA_ALCHEMY_DEVBOARD | 158 | config PCMCIA_ALCHEMY_DEVBOARD |
163 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" | 159 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" |
164 | depends on MIPS_ALCHEMY && PCMCIA | 160 | depends on MIPS_ALCHEMY && PCMCIA |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 29935ea921df..ec543a4ff2e4 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -29,7 +29,6 @@ obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o | |||
29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o | 29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o |
30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o | 30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o |
31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o | 31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o |
32 | obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o | ||
33 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o | 32 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o |
34 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o | 33 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o |
35 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o | 34 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o |
@@ -39,9 +38,6 @@ obj-$(CONFIG_AT91_CF) += at91_cf.o | |||
39 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o | 38 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o |
40 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o | 39 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o |
41 | 40 | ||
42 | au1x00_ss-y += au1000_generic.o | ||
43 | au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o | ||
44 | |||
45 | sa1111_cs-y += sa1111_generic.o | 41 | sa1111_cs-y += sa1111_generic.o |
46 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o | 42 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o |
47 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o | 43 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c deleted file mode 100644 index 95dd7c62741f..000000000000 --- a/drivers/pcmcia/au1000_generic.c +++ /dev/null | |||
@@ -1,545 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Alchemy Semi Au1000 pcmcia driver | ||
4 | * | ||
5 | * Copyright 2001-2003 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * ppopov@embeddedalley.com or source@mvista.com | ||
8 | * | ||
9 | * Copyright 2004 Pete Popov, Embedded Alley Solutions, Inc. | ||
10 | * Updated the driver to 2.6. Followed the sa11xx API and largely | ||
11 | * copied many of the hardware independent functions. | ||
12 | * | ||
13 | * ######################################################################## | ||
14 | * | ||
15 | * This program is free software; you can distribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License (Version 2) as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
20 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
22 | * for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
27 | * | ||
28 | * ######################################################################## | ||
29 | * | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/moduleparam.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/cpufreq.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/timer.h> | ||
40 | #include <linux/mm.h> | ||
41 | #include <linux/notifier.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/mutex.h> | ||
45 | #include <linux/platform_device.h> | ||
46 | #include <linux/slab.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | #include <asm/irq.h> | ||
50 | #include <asm/system.h> | ||
51 | |||
52 | #include <asm/mach-au1x00/au1000.h> | ||
53 | #include "au1000_generic.h" | ||
54 | |||
55 | MODULE_LICENSE("GPL"); | ||
56 | MODULE_AUTHOR("Pete Popov <ppopov@embeddedalley.com>"); | ||
57 | MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller"); | ||
58 | |||
59 | #if 0 | ||
60 | #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) | ||
61 | #else | ||
62 | #define debug(x,args...) | ||
63 | #endif | ||
64 | |||
65 | #define MAP_SIZE 0x100000 | ||
66 | extern struct au1000_pcmcia_socket au1000_pcmcia_socket[]; | ||
67 | #define PCMCIA_SOCKET(x) (au1000_pcmcia_socket + (x)) | ||
68 | #define to_au1000_socket(x) container_of(x, struct au1000_pcmcia_socket, socket) | ||
69 | |||
70 | /* Some boards like to support CF cards as IDE root devices, so they | ||
71 | * grab pcmcia sockets directly. | ||
72 | */ | ||
73 | u32 *pcmcia_base_vaddrs[2]; | ||
74 | extern const unsigned long mips_io_port_base; | ||
75 | |||
76 | static DEFINE_MUTEX(pcmcia_sockets_lock); | ||
77 | |||
78 | static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = { | ||
79 | au1x_board_init, | ||
80 | }; | ||
81 | |||
82 | static int | ||
83 | au1x00_pcmcia_skt_state(struct au1000_pcmcia_socket *skt) | ||
84 | { | ||
85 | struct pcmcia_state state; | ||
86 | unsigned int stat; | ||
87 | |||
88 | memset(&state, 0, sizeof(struct pcmcia_state)); | ||
89 | |||
90 | skt->ops->socket_state(skt, &state); | ||
91 | |||
92 | stat = state.detect ? SS_DETECT : 0; | ||
93 | stat |= state.ready ? SS_READY : 0; | ||
94 | stat |= state.wrprot ? SS_WRPROT : 0; | ||
95 | stat |= state.vs_3v ? SS_3VCARD : 0; | ||
96 | stat |= state.vs_Xv ? SS_XVCARD : 0; | ||
97 | stat |= skt->cs_state.Vcc ? SS_POWERON : 0; | ||
98 | |||
99 | if (skt->cs_state.flags & SS_IOCARD) | ||
100 | stat |= state.bvd1 ? SS_STSCHG : 0; | ||
101 | else { | ||
102 | if (state.bvd1 == 0) | ||
103 | stat |= SS_BATDEAD; | ||
104 | else if (state.bvd2 == 0) | ||
105 | stat |= SS_BATWARN; | ||
106 | } | ||
107 | return stat; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * au100_pcmcia_config_skt | ||
112 | * | ||
113 | * Convert PCMCIA socket state to our socket configure structure. | ||
114 | */ | ||
115 | static int | ||
116 | au1x00_pcmcia_config_skt(struct au1000_pcmcia_socket *skt, socket_state_t *state) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = skt->ops->configure_socket(skt, state); | ||
121 | if (ret == 0) { | ||
122 | skt->cs_state = *state; | ||
123 | } | ||
124 | |||
125 | if (ret < 0) | ||
126 | debug("unable to configure socket %d\n", skt->nr); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | /* au1x00_pcmcia_sock_init() | ||
132 | * | ||
133 | * (Re-)Initialise the socket, turning on status interrupts | ||
134 | * and PCMCIA bus. This must wait for power to stabilise | ||
135 | * so that the card status signals report correctly. | ||
136 | * | ||
137 | * Returns: 0 | ||
138 | */ | ||
139 | static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock) | ||
140 | { | ||
141 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
142 | |||
143 | debug("initializing socket %u\n", skt->nr); | ||
144 | |||
145 | skt->ops->socket_init(skt); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * au1x00_pcmcia_suspend() | ||
151 | * | ||
152 | * Remove power on the socket, disable IRQs from the card. | ||
153 | * Turn off status interrupts, and disable the PCMCIA bus. | ||
154 | * | ||
155 | * Returns: 0 | ||
156 | */ | ||
157 | static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock) | ||
158 | { | ||
159 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
160 | |||
161 | debug("suspending socket %u\n", skt->nr); | ||
162 | |||
163 | skt->ops->socket_suspend(skt); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static DEFINE_SPINLOCK(status_lock); | ||
169 | |||
170 | /* | ||
171 | * au1x00_check_status() | ||
172 | */ | ||
173 | static void au1x00_check_status(struct au1000_pcmcia_socket *skt) | ||
174 | { | ||
175 | unsigned int events; | ||
176 | |||
177 | debug("entering PCMCIA monitoring thread\n"); | ||
178 | |||
179 | do { | ||
180 | unsigned int status; | ||
181 | unsigned long flags; | ||
182 | |||
183 | status = au1x00_pcmcia_skt_state(skt); | ||
184 | |||
185 | spin_lock_irqsave(&status_lock, flags); | ||
186 | events = (status ^ skt->status) & skt->cs_state.csc_mask; | ||
187 | skt->status = status; | ||
188 | spin_unlock_irqrestore(&status_lock, flags); | ||
189 | |||
190 | debug("events: %s%s%s%s%s%s\n", | ||
191 | events == 0 ? "<NONE>" : "", | ||
192 | events & SS_DETECT ? "DETECT " : "", | ||
193 | events & SS_READY ? "READY " : "", | ||
194 | events & SS_BATDEAD ? "BATDEAD " : "", | ||
195 | events & SS_BATWARN ? "BATWARN " : "", | ||
196 | events & SS_STSCHG ? "STSCHG " : ""); | ||
197 | |||
198 | if (events) | ||
199 | pcmcia_parse_events(&skt->socket, events); | ||
200 | } while (events); | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * au1x00_pcmcia_poll_event() | ||
205 | * Let's poll for events in addition to IRQs since IRQ only is unreliable... | ||
206 | */ | ||
207 | static void au1x00_pcmcia_poll_event(unsigned long dummy) | ||
208 | { | ||
209 | struct au1000_pcmcia_socket *skt = (struct au1000_pcmcia_socket *)dummy; | ||
210 | debug("polling for events\n"); | ||
211 | |||
212 | mod_timer(&skt->poll_timer, jiffies + AU1000_PCMCIA_POLL_PERIOD); | ||
213 | |||
214 | au1x00_check_status(skt); | ||
215 | } | ||
216 | |||
217 | /* au1x00_pcmcia_get_status() | ||
218 | * | ||
219 | * From the sa11xx_core.c: | ||
220 | * Implements the get_status() operation for the in-kernel PCMCIA | ||
221 | * service (formerly SS_GetStatus in Card Services). Essentially just | ||
222 | * fills in bits in `status' according to internal driver state or | ||
223 | * the value of the voltage detect chipselect register. | ||
224 | * | ||
225 | * As a debugging note, during card startup, the PCMCIA core issues | ||
226 | * three set_socket() commands in a row the first with RESET deasserted, | ||
227 | * the second with RESET asserted, and the last with RESET deasserted | ||
228 | * again. Following the third set_socket(), a get_status() command will | ||
229 | * be issued. The kernel is looking for the SS_READY flag (see | ||
230 | * setup_socket(), reset_socket(), and unreset_socket() in cs.c). | ||
231 | * | ||
232 | * Returns: 0 | ||
233 | */ | ||
234 | static int | ||
235 | au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) | ||
236 | { | ||
237 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
238 | |||
239 | skt->status = au1x00_pcmcia_skt_state(skt); | ||
240 | *status = skt->status; | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* au1x00_pcmcia_set_socket() | ||
246 | * Implements the set_socket() operation for the in-kernel PCMCIA | ||
247 | * service (formerly SS_SetSocket in Card Services). We more or | ||
248 | * less punt all of this work and let the kernel handle the details | ||
249 | * of power configuration, reset, &c. We also record the value of | ||
250 | * `state' in order to regurgitate it to the PCMCIA core later. | ||
251 | * | ||
252 | * Returns: 0 | ||
253 | */ | ||
254 | static int | ||
255 | au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
256 | { | ||
257 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
258 | |||
259 | debug("for sock %u\n", skt->nr); | ||
260 | |||
261 | debug("\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n", | ||
262 | (state->csc_mask==0)?"<NONE>":"", | ||
263 | (state->csc_mask&SS_DETECT)?"DETECT ":"", | ||
264 | (state->csc_mask&SS_READY)?"READY ":"", | ||
265 | (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", | ||
266 | (state->csc_mask&SS_BATWARN)?"BATWARN ":"", | ||
267 | (state->csc_mask&SS_STSCHG)?"STSCHG ":"", | ||
268 | (state->flags==0)?"<NONE>":"", | ||
269 | (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", | ||
270 | (state->flags&SS_IOCARD)?"IOCARD ":"", | ||
271 | (state->flags&SS_RESET)?"RESET ":"", | ||
272 | (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", | ||
273 | (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":""); | ||
274 | debug("\tVcc %d Vpp %d irq %d\n", | ||
275 | state->Vcc, state->Vpp, state->io_irq); | ||
276 | |||
277 | return au1x00_pcmcia_config_skt(skt, state); | ||
278 | } | ||
279 | |||
280 | int | ||
281 | au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) | ||
282 | { | ||
283 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
284 | unsigned int speed; | ||
285 | |||
286 | if(map->map>=MAX_IO_WIN){ | ||
287 | debug("map (%d) out of range\n", map->map); | ||
288 | return -1; | ||
289 | } | ||
290 | |||
291 | if(map->flags&MAP_ACTIVE){ | ||
292 | speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED; | ||
293 | skt->spd_io[map->map] = speed; | ||
294 | } | ||
295 | |||
296 | map->start=(unsigned int)(u32)skt->virt_io; | ||
297 | map->stop=map->start+MAP_SIZE; | ||
298 | return 0; | ||
299 | |||
300 | } /* au1x00_pcmcia_set_io_map() */ | ||
301 | |||
302 | |||
303 | static int | ||
304 | au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) | ||
305 | { | ||
306 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
307 | unsigned short speed = map->speed; | ||
308 | |||
309 | if(map->map>=MAX_WIN){ | ||
310 | debug("map (%d) out of range\n", map->map); | ||
311 | return -1; | ||
312 | } | ||
313 | |||
314 | if (map->flags & MAP_ATTRIB) { | ||
315 | skt->spd_attr[map->map] = speed; | ||
316 | skt->spd_mem[map->map] = 0; | ||
317 | } else { | ||
318 | skt->spd_attr[map->map] = 0; | ||
319 | skt->spd_mem[map->map] = speed; | ||
320 | } | ||
321 | |||
322 | if (map->flags & MAP_ATTRIB) { | ||
323 | map->static_start = skt->phys_attr + map->card_start; | ||
324 | } | ||
325 | else { | ||
326 | map->static_start = skt->phys_mem + map->card_start; | ||
327 | } | ||
328 | |||
329 | debug("set_mem_map %d start %08lx card_start %08x\n", | ||
330 | map->map, map->static_start, map->card_start); | ||
331 | return 0; | ||
332 | |||
333 | } /* au1x00_pcmcia_set_mem_map() */ | ||
334 | |||
335 | static struct pccard_operations au1x00_pcmcia_operations = { | ||
336 | .init = au1x00_pcmcia_sock_init, | ||
337 | .suspend = au1x00_pcmcia_suspend, | ||
338 | .get_status = au1x00_pcmcia_get_status, | ||
339 | .set_socket = au1x00_pcmcia_set_socket, | ||
340 | .set_io_map = au1x00_pcmcia_set_io_map, | ||
341 | .set_mem_map = au1x00_pcmcia_set_mem_map, | ||
342 | }; | ||
343 | |||
344 | static const char *skt_names[] = { | ||
345 | "PCMCIA socket 0", | ||
346 | "PCMCIA socket 1", | ||
347 | }; | ||
348 | |||
349 | struct skt_dev_info { | ||
350 | int nskt; | ||
351 | }; | ||
352 | |||
353 | int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) | ||
354 | { | ||
355 | struct skt_dev_info *sinfo; | ||
356 | struct au1000_pcmcia_socket *skt; | ||
357 | int ret, i; | ||
358 | |||
359 | sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); | ||
360 | if (!sinfo) { | ||
361 | ret = -ENOMEM; | ||
362 | goto out; | ||
363 | } | ||
364 | |||
365 | sinfo->nskt = nr; | ||
366 | |||
367 | /* | ||
368 | * Initialise the per-socket structure. | ||
369 | */ | ||
370 | for (i = 0; i < nr; i++) { | ||
371 | skt = PCMCIA_SOCKET(i); | ||
372 | memset(skt, 0, sizeof(*skt)); | ||
373 | |||
374 | skt->socket.resource_ops = &pccard_static_ops; | ||
375 | skt->socket.ops = &au1x00_pcmcia_operations; | ||
376 | skt->socket.owner = ops->owner; | ||
377 | skt->socket.dev.parent = dev; | ||
378 | |||
379 | init_timer(&skt->poll_timer); | ||
380 | skt->poll_timer.function = au1x00_pcmcia_poll_event; | ||
381 | skt->poll_timer.data = (unsigned long)skt; | ||
382 | skt->poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD; | ||
383 | |||
384 | skt->nr = first + i; | ||
385 | skt->irq = 255; | ||
386 | skt->dev = dev; | ||
387 | skt->ops = ops; | ||
388 | |||
389 | skt->res_skt.name = skt_names[skt->nr]; | ||
390 | skt->res_io.name = "io"; | ||
391 | skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
392 | skt->res_mem.name = "memory"; | ||
393 | skt->res_mem.flags = IORESOURCE_MEM; | ||
394 | skt->res_attr.name = "attribute"; | ||
395 | skt->res_attr.flags = IORESOURCE_MEM; | ||
396 | |||
397 | /* | ||
398 | * PCMCIA client drivers use the inb/outb macros to access the | ||
399 | * IO registers. Since mips_io_port_base is added to the | ||
400 | * access address of the mips implementation of inb/outb, | ||
401 | * we need to subtract it here because we want to access the | ||
402 | * I/O or MEM address directly, without going through this | ||
403 | * "mips_io_port_base" mechanism. | ||
404 | */ | ||
405 | if (i == 0) { | ||
406 | skt->virt_io = (void *) | ||
407 | (ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) - | ||
408 | (u32)mips_io_port_base); | ||
409 | skt->phys_attr = AU1X_SOCK0_PHYS_ATTR; | ||
410 | skt->phys_mem = AU1X_SOCK0_PHYS_MEM; | ||
411 | } | ||
412 | else { | ||
413 | skt->virt_io = (void *) | ||
414 | (ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) - | ||
415 | (u32)mips_io_port_base); | ||
416 | skt->phys_attr = AU1X_SOCK1_PHYS_ATTR; | ||
417 | skt->phys_mem = AU1X_SOCK1_PHYS_MEM; | ||
418 | } | ||
419 | pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io; | ||
420 | ret = ops->hw_init(skt); | ||
421 | |||
422 | skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD; | ||
423 | skt->socket.irq_mask = 0; | ||
424 | skt->socket.map_size = MAP_SIZE; | ||
425 | skt->socket.pci_irq = skt->irq; | ||
426 | skt->socket.io_offset = (unsigned long)skt->virt_io; | ||
427 | |||
428 | skt->status = au1x00_pcmcia_skt_state(skt); | ||
429 | |||
430 | ret = pcmcia_register_socket(&skt->socket); | ||
431 | if (ret) | ||
432 | goto out_err; | ||
433 | |||
434 | WARN_ON(skt->socket.sock != i); | ||
435 | |||
436 | add_timer(&skt->poll_timer); | ||
437 | } | ||
438 | |||
439 | dev_set_drvdata(dev, sinfo); | ||
440 | return 0; | ||
441 | |||
442 | |||
443 | out_err: | ||
444 | ops->hw_shutdown(skt); | ||
445 | while (i-- > 0) { | ||
446 | skt = PCMCIA_SOCKET(i); | ||
447 | |||
448 | del_timer_sync(&skt->poll_timer); | ||
449 | pcmcia_unregister_socket(&skt->socket); | ||
450 | if (i == 0) { | ||
451 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
452 | skt->virt_io = NULL; | ||
453 | } | ||
454 | #ifndef CONFIG_MIPS_XXS1500 | ||
455 | else { | ||
456 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
457 | skt->virt_io = NULL; | ||
458 | } | ||
459 | #endif | ||
460 | ops->hw_shutdown(skt); | ||
461 | |||
462 | } | ||
463 | kfree(sinfo); | ||
464 | out: | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | int au1x00_drv_pcmcia_remove(struct platform_device *dev) | ||
469 | { | ||
470 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); | ||
471 | int i; | ||
472 | |||
473 | mutex_lock(&pcmcia_sockets_lock); | ||
474 | platform_set_drvdata(dev, NULL); | ||
475 | |||
476 | for (i = 0; i < sinfo->nskt; i++) { | ||
477 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | ||
478 | |||
479 | del_timer_sync(&skt->poll_timer); | ||
480 | pcmcia_unregister_socket(&skt->socket); | ||
481 | skt->ops->hw_shutdown(skt); | ||
482 | au1x00_pcmcia_config_skt(skt, &dead_socket); | ||
483 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
484 | skt->virt_io = NULL; | ||
485 | } | ||
486 | |||
487 | kfree(sinfo); | ||
488 | mutex_unlock(&pcmcia_sockets_lock); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | |||
493 | /* | ||
494 | * PCMCIA "Driver" API | ||
495 | */ | ||
496 | |||
497 | static int au1x00_drv_pcmcia_probe(struct platform_device *dev) | ||
498 | { | ||
499 | int i, ret = -ENODEV; | ||
500 | |||
501 | mutex_lock(&pcmcia_sockets_lock); | ||
502 | for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) { | ||
503 | ret = au1x00_pcmcia_hw_init[i](&dev->dev); | ||
504 | if (ret == 0) | ||
505 | break; | ||
506 | } | ||
507 | mutex_unlock(&pcmcia_sockets_lock); | ||
508 | return ret; | ||
509 | } | ||
510 | |||
511 | static struct platform_driver au1x00_pcmcia_driver = { | ||
512 | .driver = { | ||
513 | .name = "au1x00-pcmcia", | ||
514 | .owner = THIS_MODULE, | ||
515 | }, | ||
516 | .probe = au1x00_drv_pcmcia_probe, | ||
517 | .remove = au1x00_drv_pcmcia_remove, | ||
518 | }; | ||
519 | |||
520 | |||
521 | /* au1x00_pcmcia_init() | ||
522 | * | ||
523 | * This routine performs low-level PCMCIA initialization and then | ||
524 | * registers this socket driver with Card Services. | ||
525 | * | ||
526 | * Returns: 0 on success, -ve error code on failure | ||
527 | */ | ||
528 | static int __init au1x00_pcmcia_init(void) | ||
529 | { | ||
530 | int error = 0; | ||
531 | error = platform_driver_register(&au1x00_pcmcia_driver); | ||
532 | return error; | ||
533 | } | ||
534 | |||
535 | /* au1x00_pcmcia_exit() | ||
536 | * Invokes the low-level kernel service to free IRQs associated with this | ||
537 | * socket controller and reset GPIO edge detection. | ||
538 | */ | ||
539 | static void __exit au1x00_pcmcia_exit(void) | ||
540 | { | ||
541 | platform_driver_unregister(&au1x00_pcmcia_driver); | ||
542 | } | ||
543 | |||
544 | module_init(au1x00_pcmcia_init); | ||
545 | module_exit(au1x00_pcmcia_exit); | ||
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h deleted file mode 100644 index 5c36bda2963b..000000000000 --- a/drivers/pcmcia/au1000_generic.h +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* | ||
2 | * Alchemy Semi Au1000 pcmcia driver include file | ||
3 | * | ||
4 | * Copyright 2001 MontaVista Software Inc. | ||
5 | * Author: MontaVista Software, Inc. | ||
6 | * ppopov@mvista.com or source@mvista.com | ||
7 | * | ||
8 | * This program is free software; you can distribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (Version 2) as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __ASM_AU1000_PCMCIA_H | ||
22 | #define __ASM_AU1000_PCMCIA_H | ||
23 | |||
24 | /* include the world */ | ||
25 | |||
26 | #include <pcmcia/ss.h> | ||
27 | #include <pcmcia/cistpl.h> | ||
28 | #include "cs_internal.h" | ||
29 | |||
30 | #define AU1000_PCMCIA_POLL_PERIOD (2*HZ) | ||
31 | #define AU1000_PCMCIA_IO_SPEED (255) | ||
32 | #define AU1000_PCMCIA_MEM_SPEED (300) | ||
33 | |||
34 | #define AU1X_SOCK0_IO 0xF00000000ULL | ||
35 | #define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL | ||
36 | #define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL | ||
37 | |||
38 | /* pcmcia socket 1 needs external glue logic so the memory map | ||
39 | * differs from board to board. | ||
40 | */ | ||
41 | #if defined(CONFIG_MIPS_PB1000) | ||
42 | #define AU1X_SOCK1_IO 0xF08000000ULL | ||
43 | #define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL | ||
44 | #define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL | ||
45 | #endif | ||
46 | |||
47 | struct pcmcia_state { | ||
48 | unsigned detect: 1, | ||
49 | ready: 1, | ||
50 | wrprot: 1, | ||
51 | bvd1: 1, | ||
52 | bvd2: 1, | ||
53 | vs_3v: 1, | ||
54 | vs_Xv: 1; | ||
55 | }; | ||
56 | |||
57 | struct pcmcia_configure { | ||
58 | unsigned sock: 8, | ||
59 | vcc: 8, | ||
60 | vpp: 8, | ||
61 | output: 1, | ||
62 | speaker: 1, | ||
63 | reset: 1; | ||
64 | }; | ||
65 | |||
66 | struct pcmcia_irqs { | ||
67 | int sock; | ||
68 | int irq; | ||
69 | const char *str; | ||
70 | }; | ||
71 | |||
72 | |||
73 | struct au1000_pcmcia_socket { | ||
74 | struct pcmcia_socket socket; | ||
75 | |||
76 | /* | ||
77 | * Info from low level handler | ||
78 | */ | ||
79 | struct device *dev; | ||
80 | unsigned int nr; | ||
81 | unsigned int irq; | ||
82 | |||
83 | /* | ||
84 | * Core PCMCIA state | ||
85 | */ | ||
86 | struct pcmcia_low_level *ops; | ||
87 | |||
88 | unsigned int status; | ||
89 | socket_state_t cs_state; | ||
90 | |||
91 | unsigned short spd_io[MAX_IO_WIN]; | ||
92 | unsigned short spd_mem[MAX_WIN]; | ||
93 | unsigned short spd_attr[MAX_WIN]; | ||
94 | |||
95 | struct resource res_skt; | ||
96 | struct resource res_io; | ||
97 | struct resource res_mem; | ||
98 | struct resource res_attr; | ||
99 | |||
100 | void * virt_io; | ||
101 | unsigned int phys_io; | ||
102 | unsigned int phys_attr; | ||
103 | unsigned int phys_mem; | ||
104 | unsigned short speed_io, speed_attr, speed_mem; | ||
105 | |||
106 | unsigned int irq_state; | ||
107 | |||
108 | struct timer_list poll_timer; | ||
109 | }; | ||
110 | |||
111 | struct pcmcia_low_level { | ||
112 | struct module *owner; | ||
113 | |||
114 | int (*hw_init)(struct au1000_pcmcia_socket *); | ||
115 | void (*hw_shutdown)(struct au1000_pcmcia_socket *); | ||
116 | |||
117 | void (*socket_state)(struct au1000_pcmcia_socket *, struct pcmcia_state *); | ||
118 | int (*configure_socket)(struct au1000_pcmcia_socket *, struct socket_state_t *); | ||
119 | |||
120 | /* | ||
121 | * Enable card status IRQs on (re-)initialisation. This can | ||
122 | * be called at initialisation, power management event, or | ||
123 | * pcmcia event. | ||
124 | */ | ||
125 | void (*socket_init)(struct au1000_pcmcia_socket *); | ||
126 | |||
127 | /* | ||
128 | * Disable card status IRQs and PCMCIA bus on suspend. | ||
129 | */ | ||
130 | void (*socket_suspend)(struct au1000_pcmcia_socket *); | ||
131 | }; | ||
132 | |||
133 | extern int au1x_board_init(struct device *dev); | ||
134 | |||
135 | #endif /* __ASM_AU1000_PCMCIA_H */ | ||
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c deleted file mode 100644 index b2396647a165..000000000000 --- a/drivers/pcmcia/au1000_pb1x00.c +++ /dev/null | |||
@@ -1,294 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Alchemy Semi Pb1000 boards specific pcmcia routines. | ||
4 | * | ||
5 | * Copyright 2002 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * ppopov@mvista.com or source@mvista.com | ||
8 | * | ||
9 | * ######################################################################## | ||
10 | * | ||
11 | * This program is free software; you can distribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License (Version 2) as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
18 | * for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/types.h> | ||
33 | |||
34 | #include <pcmcia/ss.h> | ||
35 | #include <pcmcia/cistpl.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/system.h> | ||
40 | |||
41 | #include <asm/au1000.h> | ||
42 | #include <asm/au1000_pcmcia.h> | ||
43 | |||
44 | #define debug(fmt, arg...) do { } while (0) | ||
45 | |||
46 | #include <asm/pb1000.h> | ||
47 | #define PCMCIA_IRQ AU1000_GPIO_15 | ||
48 | |||
49 | static int pb1x00_pcmcia_init(struct pcmcia_init *init) | ||
50 | { | ||
51 | u16 pcr; | ||
52 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
53 | |||
54 | au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */ | ||
55 | au_sync_delay(100); | ||
56 | au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */ | ||
57 | au_sync(); | ||
58 | |||
59 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
60 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
61 | au_writel(pcr, PB1000_PCR); | ||
62 | au_sync_delay(20); | ||
63 | |||
64 | return PCMCIA_NUM_SOCKS; | ||
65 | } | ||
66 | |||
67 | static int pb1x00_pcmcia_shutdown(void) | ||
68 | { | ||
69 | u16 pcr; | ||
70 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
71 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
72 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
73 | au_writel(pcr, PB1000_PCR); | ||
74 | au_sync_delay(20); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) | ||
80 | { | ||
81 | u32 inserted0, inserted1; | ||
82 | u16 vs0, vs1; | ||
83 | |||
84 | vs0 = vs1 = (u16)au_readl(PB1000_ACR1); | ||
85 | inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2)); | ||
86 | inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2)); | ||
87 | vs0 = (vs0 >> 4) & 0x3; | ||
88 | vs1 = (vs1 >> 12) & 0x3; | ||
89 | |||
90 | state->ready = 0; | ||
91 | state->vs_Xv = 0; | ||
92 | state->vs_3v = 0; | ||
93 | state->detect = 0; | ||
94 | |||
95 | if (sock == 0) { | ||
96 | if (inserted0) { | ||
97 | switch (vs0) { | ||
98 | case 0: | ||
99 | case 2: | ||
100 | state->vs_3v=1; | ||
101 | break; | ||
102 | case 3: /* 5V */ | ||
103 | break; | ||
104 | default: | ||
105 | /* return without setting 'detect' */ | ||
106 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
107 | vs0); | ||
108 | return 0; | ||
109 | } | ||
110 | state->detect = 1; | ||
111 | } | ||
112 | } | ||
113 | else { | ||
114 | if (inserted1) { | ||
115 | switch (vs1) { | ||
116 | case 0: | ||
117 | case 2: | ||
118 | state->vs_3v=1; | ||
119 | break; | ||
120 | case 3: /* 5V */ | ||
121 | break; | ||
122 | default: | ||
123 | /* return without setting 'detect' */ | ||
124 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
125 | vs1); | ||
126 | return 0; | ||
127 | } | ||
128 | state->detect = 1; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (state->detect) { | ||
133 | state->ready = 1; | ||
134 | } | ||
135 | |||
136 | state->bvd1=1; | ||
137 | state->bvd2=1; | ||
138 | state->wrprot=0; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | |||
143 | static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) | ||
144 | { | ||
145 | |||
146 | if(info->sock > PCMCIA_MAX_SOCK) return -1; | ||
147 | |||
148 | /* | ||
149 | * Even in the case of the Pb1000, both sockets are connected | ||
150 | * to the same irq line. | ||
151 | */ | ||
152 | info->irq = PCMCIA_IRQ; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
158 | static int | ||
159 | pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) | ||
160 | { | ||
161 | u16 pcr; | ||
162 | |||
163 | if(configure->sock > PCMCIA_MAX_SOCK) return -1; | ||
164 | |||
165 | pcr = au_readl(PB1000_PCR); | ||
166 | |||
167 | if (configure->sock == 0) { | ||
168 | pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | | ||
169 | PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1); | ||
170 | } | ||
171 | else { | ||
172 | pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | | ||
173 | PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1); | ||
174 | } | ||
175 | |||
176 | pcr &= ~PCR_SLOT_0_RST; | ||
177 | debug("Vcc %dV Vpp %dV, pcr %x\n", | ||
178 | configure->vcc, configure->vpp, pcr); | ||
179 | switch(configure->vcc){ | ||
180 | case 0: /* Vcc 0 */ | ||
181 | switch(configure->vpp) { | ||
182 | case 0: | ||
183 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND, | ||
184 | configure->sock); | ||
185 | break; | ||
186 | case 12: | ||
187 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V, | ||
188 | configure->sock); | ||
189 | break; | ||
190 | case 50: | ||
191 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V, | ||
192 | configure->sock); | ||
193 | break; | ||
194 | case 33: | ||
195 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V, | ||
196 | configure->sock); | ||
197 | break; | ||
198 | default: | ||
199 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
200 | configure->sock); | ||
201 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
202 | __func__, | ||
203 | configure->vcc, | ||
204 | configure->vpp); | ||
205 | break; | ||
206 | } | ||
207 | break; | ||
208 | case 50: /* Vcc 5V */ | ||
209 | switch(configure->vpp) { | ||
210 | case 0: | ||
211 | pcr |= SET_VCC_VPP(VCC_5V,VPP_GND, | ||
212 | configure->sock); | ||
213 | break; | ||
214 | case 50: | ||
215 | pcr |= SET_VCC_VPP(VCC_5V,VPP_5V, | ||
216 | configure->sock); | ||
217 | break; | ||
218 | case 12: | ||
219 | pcr |= SET_VCC_VPP(VCC_5V,VPP_12V, | ||
220 | configure->sock); | ||
221 | break; | ||
222 | case 33: | ||
223 | pcr |= SET_VCC_VPP(VCC_5V,VPP_3V, | ||
224 | configure->sock); | ||
225 | break; | ||
226 | default: | ||
227 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
228 | configure->sock); | ||
229 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
230 | __func__, | ||
231 | configure->vcc, | ||
232 | configure->vpp); | ||
233 | break; | ||
234 | } | ||
235 | break; | ||
236 | case 33: /* Vcc 3.3V */ | ||
237 | switch(configure->vpp) { | ||
238 | case 0: | ||
239 | pcr |= SET_VCC_VPP(VCC_3V,VPP_GND, | ||
240 | configure->sock); | ||
241 | break; | ||
242 | case 50: | ||
243 | pcr |= SET_VCC_VPP(VCC_3V,VPP_5V, | ||
244 | configure->sock); | ||
245 | break; | ||
246 | case 12: | ||
247 | pcr |= SET_VCC_VPP(VCC_3V,VPP_12V, | ||
248 | configure->sock); | ||
249 | break; | ||
250 | case 33: | ||
251 | pcr |= SET_VCC_VPP(VCC_3V,VPP_3V, | ||
252 | configure->sock); | ||
253 | break; | ||
254 | default: | ||
255 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
256 | configure->sock); | ||
257 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
258 | __func__, | ||
259 | configure->vcc, | ||
260 | configure->vpp); | ||
261 | break; | ||
262 | } | ||
263 | break; | ||
264 | default: /* what's this ? */ | ||
265 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock); | ||
266 | printk(KERN_ERR "%s: bad Vcc %d\n", | ||
267 | __func__, configure->vcc); | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | if (configure->sock == 0) { | ||
272 | pcr &= ~(PCR_SLOT_0_RST); | ||
273 | if (configure->reset) | ||
274 | pcr |= PCR_SLOT_0_RST; | ||
275 | } | ||
276 | else { | ||
277 | pcr &= ~(PCR_SLOT_1_RST); | ||
278 | if (configure->reset) | ||
279 | pcr |= PCR_SLOT_1_RST; | ||
280 | } | ||
281 | au_writel(pcr, PB1000_PCR); | ||
282 | au_sync_delay(300); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | |||
288 | struct pcmcia_low_level pb1x00_pcmcia_ops = { | ||
289 | pb1x00_pcmcia_init, | ||
290 | pb1x00_pcmcia_shutdown, | ||
291 | pb1x00_pcmcia_socket_state, | ||
292 | pb1x00_pcmcia_get_irq_info, | ||
293 | pb1x00_pcmcia_configure_socket | ||
294 | }; | ||