aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 16:05:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-14 16:05:21 -0500
commit4964e0664c80680fa6b28ef91381c076a5b25c2c (patch)
tree62099c5aaeee7274bcc66bcfba35d479affa97cf /drivers/pcmcia
parent0a80939b3e6af4b0dc93bf88ec02fd7e90a16f1b (diff)
parent7bf6612e8a9d6a0b3b82e8e2611942be1258b307 (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (119 commits) MIPS: Delete unused function add_temporary_entry. MIPS: Set default pci cache line size. MIPS: Flush huge TLB MIPS: Octeon: Remove SYS_SUPPORTS_HIGHMEM. MIPS: Octeon: Add support for OCTEON II PCIe MIPS: Octeon: Update PCI Latency timer and enable more error reporting. MIPS: Alchemy: Update cpu-feature-overrides MIPS: Alchemy: db1200: Improve PB1200 detection. MIPS: Alchemy: merge Au1000 and Au1300-style IRQ controller code. MIPS: Alchemy: chain IRQ controllers to MIPS IRQ controller MIPS: Alchemy: irq: register pm at irq init time MIPS: Alchemy: Touchscreen support on DB1100 MIPS: Alchemy: Hook up IrDA on DB1000/DB1100 net/irda: convert au1k_ir to platform driver. MIPS: Alchemy: remove unused board headers MTD: nand: make au1550nd.c a platform_driver MIPS: Netlogic: Mark Netlogic chips as SMT capable MIPS: Netlogic: Add support for XLP 3XX cores MIPS: Netlogic: Merge some of XLR/XLP wakup code MIPS: Netlogic: Add default XLP config. ... Fix up trivial conflicts in arch/mips/kernel/{perf_event_mipsxx.c, traps.c} and drivers/tty/serial/Makefile
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig8
-rw-r--r--drivers/pcmcia/Makefile4
-rw-r--r--drivers/pcmcia/au1000_generic.c545
-rw-r--r--drivers/pcmcia/au1000_generic.h135
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c294
-rw-r--r--drivers/pcmcia/db1xxx_ss.c26
6 files changed, 24 insertions, 988 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 6e318ce41136..f9e3fb3a285b 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -155,18 +155,14 @@ 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
158config PCMCIA_AU1X00
159 tristate "Au1x00 pcmcia support"
160 depends on MIPS_ALCHEMY && PCMCIA
161
162config PCMCIA_ALCHEMY_DEVBOARD 158config 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
165 select 64BIT_PHYS_ADDR 161 select 64BIT_PHYS_ADDR
166 help 162 help
167 Enable this driver of you want PCMCIA support on your Alchemy 163 Enable this driver of you want PCMCIA support on your Alchemy
168 Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board. 164 Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300
169 NOT suitable for the PB1000! 165 board. NOT suitable for the PB1000!
170 166
171 This driver is also available as a module called db1xxx_ss.ko 167 This driver is also available as a module called db1xxx_ss.ko
172 168
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
29obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o 29obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o
30obj-$(CONFIG_M32R_PCC) += m32r_pcc.o 30obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
31obj-$(CONFIG_M32R_CFC) += m32r_cfc.o 31obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
32obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
33obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o 32obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
34obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o 33obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
35obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o 34obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
@@ -39,9 +38,6 @@ obj-$(CONFIG_AT91_CF) += at91_cf.o
39obj-$(CONFIG_ELECTRA_CF) += electra_cf.o 38obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
40obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o 39obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
41 40
42au1x00_ss-y += au1000_generic.o
43au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
44
45sa1111_cs-y += sa1111_generic.o 41sa1111_cs-y += sa1111_generic.o
46sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o 42sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
47sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o 43sa1111_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
55MODULE_LICENSE("GPL");
56MODULE_AUTHOR("Pete Popov <ppopov@embeddedalley.com>");
57MODULE_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
66extern 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 */
73u32 *pcmcia_base_vaddrs[2];
74extern const unsigned long mips_io_port_base;
75
76static DEFINE_MUTEX(pcmcia_sockets_lock);
77
78static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
79 au1x_board_init,
80};
81
82static int
83au1x00_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 */
115static int
116au1x00_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 */
139static 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 */
157static 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
168static DEFINE_SPINLOCK(status_lock);
169
170/*
171 * au1x00_check_status()
172 */
173static 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 */
207static 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 */
234static int
235au1x00_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 */
254static int
255au1x00_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
280int
281au1x00_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
303static int
304au1x00_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
335static 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
344static const char *skt_names[] = {
345 "PCMCIA socket 0",
346 "PCMCIA socket 1",
347};
348
349struct skt_dev_info {
350 int nskt;
351};
352
353int 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
443out_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);
464out:
465 return ret;
466}
467
468int 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
497static 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
511static 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 */
528static 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 */
539static void __exit au1x00_pcmcia_exit(void)
540{
541 platform_driver_unregister(&au1x00_pcmcia_driver);
542}
543
544module_init(au1x00_pcmcia_init);
545module_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
47struct 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
57struct pcmcia_configure {
58 unsigned sock: 8,
59 vcc: 8,
60 vpp: 8,
61 output: 1,
62 speaker: 1,
63 reset: 1;
64};
65
66struct pcmcia_irqs {
67 int sock;
68 int irq;
69 const char *str;
70};
71
72
73struct 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
111struct 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
133extern 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
49static 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
67static 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
78static int
79pb1x00_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
143static 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
158static int
159pb1x00_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
288struct 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};
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 3e49df6d5e3b..5b7c22784aff 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -7,7 +7,7 @@
7 7
8/* This is a fairly generic PCMCIA socket driver suitable for the 8/* This is a fairly generic PCMCIA socket driver suitable for the
9 * following Alchemy Development boards: 9 * following Alchemy Development boards:
10 * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200. 10 * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200, Db1300
11 * 11 *
12 * The Db1000 is used as a reference: Per-socket card-, carddetect- and 12 * The Db1000 is used as a reference: Per-socket card-, carddetect- and
13 * statuschange IRQs connected to SoC GPIOs, control and status register 13 * statuschange IRQs connected to SoC GPIOs, control and status register
@@ -18,6 +18,7 @@
18 * - Pb1100/Pb1500: single socket only; voltage key bits VS are 18 * - Pb1100/Pb1500: single socket only; voltage key bits VS are
19 * at STATUS[5:4] (instead of STATUS[1:0]). 19 * at STATUS[5:4] (instead of STATUS[1:0]).
20 * - Au1200-based: additional card-eject irqs, irqs not gpios! 20 * - Au1200-based: additional card-eject irqs, irqs not gpios!
21 * - Db1300: Db1200-like, no pwr ctrl, single socket (#1).
21 */ 22 */
22 23
23#include <linux/delay.h> 24#include <linux/delay.h>
@@ -59,11 +60,17 @@ struct db1x_pcmcia_sock {
59#define BOARD_TYPE_DEFAULT 0 /* most boards */ 60#define BOARD_TYPE_DEFAULT 0 /* most boards */
60#define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */ 61#define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */
61#define BOARD_TYPE_PB1100 2 /* VS bits slightly different */ 62#define BOARD_TYPE_PB1100 2 /* VS bits slightly different */
63#define BOARD_TYPE_DB1300 3 /* no power control */
62 int board_type; 64 int board_type;
63}; 65};
64 66
65#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket) 67#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
66 68
69static int db1300_card_inserted(struct db1x_pcmcia_sock *sock)
70{
71 return bcsr_read(BCSR_SIGSTAT) & (1 << 8);
72}
73
67/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */ 74/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
68static int db1200_card_inserted(struct db1x_pcmcia_sock *sock) 75static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
69{ 76{
@@ -84,6 +91,8 @@ static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
84 switch (sock->board_type) { 91 switch (sock->board_type) {
85 case BOARD_TYPE_DB1200: 92 case BOARD_TYPE_DB1200:
86 return db1200_card_inserted(sock); 93 return db1200_card_inserted(sock);
94 case BOARD_TYPE_DB1300:
95 return db1300_card_inserted(sock);
87 default: 96 default:
88 return db1000_card_inserted(sock); 97 return db1000_card_inserted(sock);
89 } 98 }
@@ -160,7 +169,8 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
160 * ejection handler have been registered and the currently 169 * ejection handler have been registered and the currently
161 * active one disabled. 170 * active one disabled.
162 */ 171 */
163 if (sock->board_type == BOARD_TYPE_DB1200) { 172 if ((sock->board_type == BOARD_TYPE_DB1200) ||
173 (sock->board_type == BOARD_TYPE_DB1300)) {
164 ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, 174 ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
165 IRQF_DISABLED, "pcmcia_insert", sock); 175 IRQF_DISABLED, "pcmcia_insert", sock);
166 if (ret) 176 if (ret)
@@ -174,7 +184,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
174 } 184 }
175 185
176 /* enable the currently silent one */ 186 /* enable the currently silent one */
177 if (db1200_card_inserted(sock)) 187 if (db1x_card_inserted(sock))
178 enable_irq(sock->eject_irq); 188 enable_irq(sock->eject_irq);
179 else 189 else
180 enable_irq(sock->insert_irq); 190 enable_irq(sock->insert_irq);
@@ -270,7 +280,8 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
270 } 280 }
271 281
272 /* create new voltage code */ 282 /* create new voltage code */
273 cr_set |= ((v << 2) | p) << (sock->nr * 8); 283 if (sock->board_type != BOARD_TYPE_DB1300)
284 cr_set |= ((v << 2) | p) << (sock->nr * 8);
274 285
275 changed = state->flags ^ sock->old_flags; 286 changed = state->flags ^ sock->old_flags;
276 287
@@ -343,6 +354,10 @@ static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
343 /* if Vcc is not zero, we have applied power to a card */ 354 /* if Vcc is not zero, we have applied power to a card */
344 status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0; 355 status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
345 356
357 /* DB1300: power always on, but don't tell when no card present */
358 if ((sock->board_type == BOARD_TYPE_DB1300) && (status & SS_DETECT))
359 status = SS_POWERON | SS_3VCARD | SS_DETECT;
360
346 /* reset de-asserted? then we're ready */ 361 /* reset de-asserted? then we're ready */
347 status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET; 362 status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
348 363
@@ -419,6 +434,9 @@ static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
419 case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200: 434 case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
420 sock->board_type = BOARD_TYPE_DB1200; 435 sock->board_type = BOARD_TYPE_DB1200;
421 break; 436 break;
437 case BCSR_WHOAMI_DB1300:
438 sock->board_type = BOARD_TYPE_DB1300;
439 break;
422 default: 440 default:
423 printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); 441 printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
424 ret = -ENODEV; 442 ret = -ENODEV;