3 * bcm47xx pcmcia driver
5 * Copyright 2004, Broadcom Corporation
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13 * Based on sa1100_generic.c from www.handhelds.org,
14 * and au1000_generic.c from oss.sgi.com.
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/config.h>
21 #include <linux/delay.h>
22 #include <linux/ioport.h>
23 #include <linux/kernel.h>
24 #include <linux/tqueue.h>
25 #include <linux/timer.h>
27 #include <linux/proc_fs.h>
28 #include <linux/version.h>
29 #include <linux/types.h>
30 #include <linux/vmalloc.h>
32 #include <pcmcia/version.h>
33 #include <pcmcia/cs_types.h>
34 #include <pcmcia/cs.h>
35 #include <pcmcia/ss.h>
36 #include <pcmcia/bulkmem.h>
37 #include <pcmcia/cistpl.h>
38 #include <pcmcia/bus_ops.h>
39 #include "cs_internal.h"
43 #include <asm/system.h>
49 #include "bcm4710pcmcia.h"
52 static int pc_debug = PCMCIA_DEBUG;
55 MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller");
57 /* This structure maintains housekeeping state for each socket, such
58 * as the last known values of the card detect pins, or the Card Services
59 * callback value associated with the socket:
61 static struct bcm47xx_pcmcia_socket *pcmcia_socket;
62 static int socket_count;
65 /* Returned by the low-level PCMCIA interface: */
66 static struct pcmcia_low_level *pcmcia_low_level;
68 /* Event poll timer structure */
69 static struct timer_list poll_timer;
72 /* Prototypes for routines which are used internally: */
74 static int bcm47xx_pcmcia_driver_init(void);
75 static void bcm47xx_pcmcia_driver_shutdown(void);
76 static void bcm47xx_pcmcia_task_handler(void *data);
77 static void bcm47xx_pcmcia_poll_event(unsigned long data);
78 static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
79 static struct tq_struct bcm47xx_pcmcia_task;
82 static int bcm47xx_pcmcia_proc_status(char *buf, char **start,
83 off_t pos, int count, int *eof, void *data);
87 /* Prototypes for operations which are exported to the
88 * in-kernel PCMCIA core:
91 static int bcm47xx_pcmcia_init(unsigned int sock);
92 static int bcm47xx_pcmcia_suspend(unsigned int sock);
93 static int bcm47xx_pcmcia_register_callback(unsigned int sock,
94 void (*handler)(void *, unsigned int), void *info);
95 static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap);
96 static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value);
97 static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state);
98 static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state);
99 static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io);
100 static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io);
101 static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
102 static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
103 #ifdef CONFIG_PROC_FS
104 static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base);
107 static struct pccard_operations bcm47xx_pcmcia_operations = {
109 bcm47xx_pcmcia_suspend,
110 bcm47xx_pcmcia_register_callback,
111 bcm47xx_pcmcia_inquire_socket,
112 bcm47xx_pcmcia_get_status,
113 bcm47xx_pcmcia_get_socket,
114 bcm47xx_pcmcia_set_socket,
115 bcm47xx_pcmcia_get_io_map,
116 bcm47xx_pcmcia_set_io_map,
117 bcm47xx_pcmcia_get_mem_map,
118 bcm47xx_pcmcia_set_mem_map,
119 #ifdef CONFIG_PROC_FS
120 bcm47xx_pcmcia_proc_setup
126 * bcm47xx_pcmcia_driver_init()
128 * This routine performs a basic sanity check to ensure that this
129 * kernel has been built with the appropriate board-specific low-level
130 * PCMCIA support, performs low-level PCMCIA initialization, registers
131 * this socket driver with Card Services, and then spawns the daemon
132 * thread which is the real workhorse of the socket driver.
134 * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
135 * on the low-level kernel interface.
137 * Returns: 0 on success, -1 on error
139 static int __init bcm47xx_pcmcia_driver_init(void)
142 struct pcmcia_init pcmcia_init;
143 struct pcmcia_state state;
148 printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);
150 CardServices(GetCardServicesInfo, &info);
152 if (info.Revision != CS_RELEASE_CODE) {
153 printk(KERN_ERR "Card Services release codes do not match\n");
157 #ifdef CONFIG_BCM4710
158 pcmcia_low_level=&bcm4710_pcmcia_ops;
160 #error Unsupported Broadcom BCM47XX board.
163 pcmcia_init.handler=bcm47xx_pcmcia_interrupt;
165 if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
166 printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
169 printk("\t%d PCMCIA sockets initialized.\n", socket_count);
173 kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count,
175 memset(pcmcia_socket, 0,
176 sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
177 if (!pcmcia_socket) {
178 printk(KERN_ERR "Card Services can't get memory \n");
182 for (i = 0; i < socket_count; i++) {
183 if (pcmcia_low_level->socket_state(i, &state) < 0) {
184 printk(KERN_ERR "Unable to get PCMCIA status\n");
187 pcmcia_socket[i].k_state = state;
188 pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
191 pcmcia_socket[i].virt_io =
192 (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000);
193 /* Substract ioport base which gets added by in/out */
194 pcmcia_socket[i].virt_io -= mips_io_port_base;
195 pcmcia_socket[i].phys_attr =
196 (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF);
197 pcmcia_socket[i].phys_mem =
198 (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF);
200 printk(KERN_ERR "bcm4710: socket 1 not supported\n");
205 /* Only advertise as many sockets as we can detect: */
206 if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
207 printk(KERN_ERR "Unable to register socket service routine\n");
211 /* Start the event poll timer.
212 * It will reschedule by itself afterwards.
214 bcm47xx_pcmcia_poll_event(0);
216 DEBUG(1, "bcm4710: initialization complete\n");
221 module_init(bcm47xx_pcmcia_driver_init);
225 * bcm47xx_pcmcia_driver_shutdown()
227 * Invokes the low-level kernel service to free IRQs associated with this
228 * socket controller and reset GPIO edge detection.
230 static void __exit bcm47xx_pcmcia_driver_shutdown(void)
234 del_timer_sync(&poll_timer);
235 unregister_ss_entry(&bcm47xx_pcmcia_operations);
236 pcmcia_low_level->shutdown();
237 flush_scheduled_tasks();
238 for (i = 0; i < socket_count; i++) {
239 if (pcmcia_socket[i].virt_io)
240 iounmap((void *)pcmcia_socket[i].virt_io);
241 if (pcmcia_socket[i].phys_attr)
242 iounmap((void *)pcmcia_socket[i].phys_attr);
243 if (pcmcia_socket[i].phys_mem)
244 iounmap((void *)pcmcia_socket[i].phys_mem);
246 DEBUG(1, "bcm4710: shutdown complete\n");
249 module_exit(bcm47xx_pcmcia_driver_shutdown);
252 * bcm47xx_pcmcia_init()
253 * We perform all of the interesting initialization tasks in
254 * bcm47xx_pcmcia_driver_init().
258 static int bcm47xx_pcmcia_init(unsigned int sock)
260 DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock);
266 * bcm47xx_pcmcia_suspend()
268 * We don't currently perform any actions on a suspend.
272 static int bcm47xx_pcmcia_suspend(unsigned int sock)
274 DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock);
281 * bcm47xx_pcmcia_events()
283 * Helper routine to generate a Card Services event mask based on
284 * state information obtained from the kernel low-level PCMCIA layer
285 * in a recent (and previous) sampling. Updates `prev_state'.
287 * Returns: an event mask for the given socket state.
289 static inline unsigned
290 bcm47xx_pcmcia_events(struct pcmcia_state *state,
291 struct pcmcia_state *prev_state,
292 unsigned int mask, unsigned int flags)
294 unsigned int events=0;
296 if (state->bvd1 != prev_state->bvd1) {
298 DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
300 events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD;
303 if (state->bvd2 != prev_state->bvd2) {
305 DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
307 events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN;
310 if (state->detect != prev_state->detect) {
312 DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
314 events |= mask & SS_DETECT;
318 if (state->ready != prev_state->ready) {
320 DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
322 events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY);
326 DEBUG(2, "events: %s%s%s%s%s\n",
327 (events & SS_DETECT) ? "DETECT " : "",
328 (events & SS_READY) ? "READY " : "",
329 (events & SS_BATDEAD) ? "BATDEAD " : "",
330 (events & SS_BATWARN) ? "BATWARN " : "",
331 (events & SS_STSCHG) ? "STSCHG " : "");
340 * bcm47xx_pcmcia_task_handler()
342 * Processes serviceable socket events using the "eventd" thread context.
344 * Event processing (specifically, the invocation of the Card Services event
345 * callback) occurs in this thread rather than in the actual interrupt
346 * handler due to the use of scheduling operations in the PCMCIA core.
348 static void bcm47xx_pcmcia_task_handler(void *data)
350 struct pcmcia_state state;
351 int i, events, irq_status;
353 DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
355 for (i = 0; i < socket_count; i++) {
356 if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0)
357 printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
359 events = bcm47xx_pcmcia_events(&state,
360 &pcmcia_socket[i].k_state,
361 pcmcia_socket[i].cs_state.csc_mask,
362 pcmcia_socket[i].cs_state.flags);
364 if (pcmcia_socket[i].handler != NULL) {
365 pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
371 static struct tq_struct bcm47xx_pcmcia_task = {
372 routine: bcm47xx_pcmcia_task_handler
377 * bcm47xx_pcmcia_poll_event()
379 * Let's poll for events in addition to IRQs since IRQ only is unreliable...
381 static void bcm47xx_pcmcia_poll_event(unsigned long dummy)
383 DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
385 poll_timer.function = bcm47xx_pcmcia_poll_event;
386 poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD;
387 add_timer(&poll_timer);
388 schedule_task(&bcm47xx_pcmcia_task);
393 * bcm47xx_pcmcia_interrupt()
395 * Service routine for socket driver interrupts (requested by the
396 * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()).
398 * The actual interrupt-servicing work is performed by
399 * bcm47xx_pcmcia_task(), largely because the Card Services event-
400 * handling code performs scheduling operations which cannot be
401 * executed from within an interrupt context.
404 bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
406 DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
407 schedule_task(&bcm47xx_pcmcia_task);
412 * bcm47xx_pcmcia_register_callback()
414 * Implements the register_callback() operation for the in-kernel
415 * PCMCIA service (formerly SS_RegisterCallback in Card Services). If
416 * the function pointer `handler' is not NULL, remember the callback
417 * location in the state for `sock', and increment the usage counter
418 * for the driver module. (The callback is invoked from the interrupt
419 * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services
420 * of interesting events.) Otherwise, clear the callback pointer in the
421 * socket state and decrement the module usage count.
426 bcm47xx_pcmcia_register_callback(unsigned int sock,
427 void (*handler)(void *, unsigned int), void *info)
429 if (handler == NULL) {
430 pcmcia_socket[sock].handler = NULL;
434 pcmcia_socket[sock].handler = handler;
435 pcmcia_socket[sock].handler_info = info;
442 * bcm47xx_pcmcia_inquire_socket()
444 * Implements the inquire_socket() operation for the in-kernel PCMCIA
445 * service (formerly SS_InquireSocket in Card Services). Of note is
446 * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
447 * `cap' to "trick" Card Services into tolerating large "I/O memory"
448 * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
449 * resource database check. (Mapped memory is set up within the socket
452 * In conjunction with the STATIC_MAP capability is a new field,
453 * `io_offset', recommended by David Hinds. Rather than go through
454 * the SetIOMap interface (which is not quite suited for communicating
455 * window locations up from the socket driver), we just pass up
456 * an offset which is applied to client-requested base I/O addresses
457 * in alloc_io_space().
459 * Returns: 0 on success, -1 if no pin has been configured for `sock'
462 bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
464 struct pcmcia_irq_info irq_info;
466 if (sock >= socket_count) {
467 printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock);
471 /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
472 * force_low argument to validate_mem() in rsrc_mgr.c -- since in
473 * general, the mapped * addresses of the PCMCIA memory regions
474 * will not be within 0xffff, setting force_low would be
477 * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
478 * resource database; we instead pass up physical address ranges
479 * and allow other parts of Card Services to deal with remapping.
481 * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
482 * not 32-bit CardBus devices.
484 cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
486 irq_info.sock = sock;
489 if (pcmcia_low_level->get_irq_info(&irq_info) < 0) {
490 printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
495 cap->map_size = PAGE_SIZE;
496 cap->pci_irq = irq_info.irq;
497 cap->io_offset = pcmcia_socket[sock].virt_io;
504 * bcm47xx_pcmcia_get_status()
506 * Implements the get_status() operation for the in-kernel PCMCIA
507 * service (formerly SS_GetStatus in Card Services). Essentially just
508 * fills in bits in `status' according to internal driver state or
509 * the value of the voltage detect chipselect register.
511 * As a debugging note, during card startup, the PCMCIA core issues
512 * three set_socket() commands in a row the first with RESET deasserted,
513 * the second with RESET asserted, and the last with RESET deasserted
514 * again. Following the third set_socket(), a get_status() command will
515 * be issued. The kernel is looking for the SS_READY flag (see
516 * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
521 bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status)
523 struct pcmcia_state state;
526 if ((pcmcia_low_level->socket_state(sock, &state)) < 0) {
527 printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
531 pcmcia_socket[sock].k_state = state;
533 *status = state.detect ? SS_DETECT : 0;
535 *status |= state.ready ? SS_READY : 0;
537 /* The power status of individual sockets is not available
538 * explicitly from the hardware, so we just remember the state
539 * and regurgitate it upon request:
541 *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0;
543 if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD)
544 *status |= state.bvd1 ? SS_STSCHG : 0;
547 *status |= SS_BATDEAD;
548 else if (state.bvd2 == 0)
549 *status |= SS_BATWARN;
552 *status |= state.vs_3v ? SS_3VCARD : 0;
554 *status |= state.vs_Xv ? SS_XVCARD : 0;
556 DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
557 (*status&SS_DETECT)?"DETECT ":"",
558 (*status&SS_READY)?"READY ":"",
559 (*status&SS_BATDEAD)?"BATDEAD ":"",
560 (*status&SS_BATWARN)?"BATWARN ":"",
561 (*status&SS_POWERON)?"POWERON ":"",
562 (*status&SS_STSCHG)?"STSCHG ":"",
563 (*status&SS_3VCARD)?"3VCARD ":"",
564 (*status&SS_XVCARD)?"XVCARD ":"");
571 * bcm47xx_pcmcia_get_socket()
573 * Implements the get_socket() operation for the in-kernel PCMCIA
574 * service (formerly SS_GetSocket in Card Services). Not a very
580 bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
582 DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
584 /* This information was given to us in an earlier call to set_socket(),
585 * so we're just regurgitating it here:
587 *state = pcmcia_socket[sock].cs_state;
593 * bcm47xx_pcmcia_set_socket()
595 * Implements the set_socket() operation for the in-kernel PCMCIA
596 * service (formerly SS_SetSocket in Card Services). We more or
597 * less punt all of this work and let the kernel handle the details
598 * of power configuration, reset, &c. We also record the value of
599 * `state' in order to regurgitate it to the PCMCIA core later.
604 bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
606 struct pcmcia_configure configure;
608 DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
609 "\tVcc %d Vpp %d irq %d\n",
610 (state->csc_mask == 0) ? "<NONE>" : "",
611 (state->csc_mask & SS_DETECT) ? "DETECT " : "",
612 (state->csc_mask & SS_READY) ? "READY " : "",
613 (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
614 (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
615 (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
616 (state->flags == 0) ? "<NONE>" : "",
617 (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
618 (state->flags & SS_IOCARD) ? "IOCARD " : "",
619 (state->flags & SS_RESET) ? "RESET " : "",
620 (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
621 (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
622 state->Vcc, state->Vpp, state->io_irq);
624 configure.sock = sock;
625 configure.vcc = state->Vcc;
626 configure.vpp = state->Vpp;
627 configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0;
628 configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0;
629 configure.reset = (state->flags & SS_RESET) ? 1 : 0;
631 if (pcmcia_low_level->configure_socket(&configure) < 0) {
632 printk(KERN_ERR "Unable to configure socket %u\n", sock);
636 pcmcia_socket[sock].cs_state = *state;
642 * bcm47xx_pcmcia_get_io_map()
644 * Implements the get_io_map() operation for the in-kernel PCMCIA
645 * service (formerly SS_GetIOMap in Card Services). Just returns an
646 * I/O map descriptor which was assigned earlier by a set_io_map().
648 * Returns: 0 on success, -1 if the map index was out of range
651 bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
653 DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock);
655 if (map->map >= MAX_IO_WIN) {
656 printk(KERN_ERR "%s(): map (%d) out of range\n",
657 __FUNCTION__, map->map);
661 *map = pcmcia_socket[sock].io_map[map->map];
667 * bcm47xx_pcmcia_set_io_map()
669 * Implements the set_io_map() operation for the in-kernel PCMCIA
670 * service (formerly SS_SetIOMap in Card Services). We configure
671 * the map speed as requested, but override the address ranges
672 * supplied by Card Services.
674 * Returns: 0 on success, -1 on error
677 bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
682 DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n"
683 "\tflags: %s%s%s%s%s%s%s%s\n",
684 map->map, map->speed, map->start, map->stop,
685 (map->flags == 0) ? "<NONE>" : "",
686 (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
687 (map->flags & MAP_16BIT) ? "16BIT " : "",
688 (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
689 (map->flags & MAP_0WS) ? "0WS " : "",
690 (map->flags & MAP_WRPROT) ? "WRPROT " : "",
691 (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
692 (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
694 if (map->map >= MAX_IO_WIN) {
695 printk(KERN_ERR "%s(): map (%d) out of range\n",
696 __FUNCTION__, map->map);
700 if (map->flags & MAP_ACTIVE) {
701 speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED;
702 pcmcia_socket[sock].speed_io = speed;
707 if (map->stop == 1) {
708 map->stop = PAGE_SIZE - 1;
711 map->start = pcmcia_socket[sock].virt_io;
712 map->stop = map->start + (map->stop - start);
713 pcmcia_socket[sock].io_map[map->map] = *map;
714 DEBUG(2, "set_io_map %d start %x stop %x\n",
715 map->map, map->start, map->stop);
721 * bcm47xx_pcmcia_get_mem_map()
723 * Implements the get_mem_map() operation for the in-kernel PCMCIA
724 * service (formerly SS_GetMemMap in Card Services). Just returns a
725 * memory map descriptor which was assigned earlier by a
726 * set_mem_map() request.
728 * Returns: 0 on success, -1 if the map index was out of range
731 bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
733 DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
735 if (map->map >= MAX_WIN) {
736 printk(KERN_ERR "%s(): map (%d) out of range\n",
737 __FUNCTION__, map->map);
741 *map = pcmcia_socket[sock].mem_map[map->map];
747 * bcm47xx_pcmcia_set_mem_map()
749 * Implements the set_mem_map() operation for the in-kernel PCMCIA
750 * service (formerly SS_SetMemMap in Card Services). We configure
751 * the map speed as requested, but override the address ranges
752 * supplied by Card Services.
754 * Returns: 0 on success, -1 on error
757 bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
763 if (map->map >= MAX_WIN) {
764 printk(KERN_ERR "%s(): map (%d) out of range\n",
765 __FUNCTION__, map->map);
769 DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n"
770 "\tsys_stop %#lx\n\tcard_start %#x\n"
771 "\tflags: %s%s%s%s%s%s%s%s\n",
772 map->map, map->speed, map->sys_start, map->sys_stop,
773 map->card_start, (map->flags == 0) ? "<NONE>" : "",
774 (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
775 (map->flags & MAP_16BIT) ? "16BIT " : "",
776 (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
777 (map->flags & MAP_0WS) ? "0WS " : "",
778 (map->flags & MAP_WRPROT) ? "WRPROT " : "",
779 (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
780 (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
782 if (map->flags & MAP_ACTIVE) {
783 /* When clients issue RequestMap, the access speed is not always
784 * properly configured:
786 speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED;
789 if (map->flags & MAP_ATTRIB) {
790 pcmcia_socket[sock].speed_attr = speed;
792 pcmcia_socket[sock].speed_mem = speed;
798 start = map->sys_start;
800 if (map->sys_stop == 0)
801 map->sys_stop = PAGE_SIZE - 1;
803 if (map->flags & MAP_ATTRIB) {
804 map->sys_start = pcmcia_socket[sock].phys_attr +
807 map->sys_start = pcmcia_socket[sock].phys_mem +
811 map->sys_stop = map->sys_start + (map->sys_stop - start);
812 pcmcia_socket[sock].mem_map[map->map] = *map;
813 restore_flags(flags);
814 DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n",
815 map->map, map->sys_start, map->sys_stop,
821 #if defined(CONFIG_PROC_FS)
824 * bcm47xx_pcmcia_proc_setup()
826 * Implements the proc_setup() operation for the in-kernel PCMCIA
827 * service (formerly SS_ProcSetup in Card Services).
829 * Returns: 0 on success, -1 on error
832 bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
834 struct proc_dir_entry *entry;
836 if ((entry = create_proc_entry("status", 0, base)) == NULL) {
837 printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
841 entry->read_proc = bcm47xx_pcmcia_proc_status;
842 entry->data = (void *)sock;
847 * bcm47xx_pcmcia_proc_status()
849 * Implements the /proc/bus/pccard/??/status file.
851 * Returns: the number of characters added to the buffer
854 bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos,
855 int count, int *eof, void *data)
858 unsigned int sock = (unsigned int)data;
860 p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
861 pcmcia_socket[sock].k_state.detect ? "detect " : "",
862 pcmcia_socket[sock].k_state.ready ? "ready " : "",
863 pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "",
864 pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "",
865 pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "",
866 pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "",
867 pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : "");
869 p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n",
870 pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "",
871 pcmcia_socket[sock].k_state.ready ? "SS_READY " : "",
872 pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "",
873 pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
874 (pcmcia_socket[sock].cs_state.flags & SS_IOCARD &&
875 pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "",
876 ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
877 (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "",
878 ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
879 (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "",
880 pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "",
881 pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : "");
883 p += sprintf(p, "mask : %s%s%s%s%s\n",
884 pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "",
885 pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "",
886 pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
887 pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
888 pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : "");
890 p += sprintf(p, "cs_flags : %s%s%s%s%s\n",
891 pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ?
893 pcmcia_socket[sock].cs_state.flags & SS_IOCARD ?
895 pcmcia_socket[sock].cs_state.flags & SS_RESET ?
897 pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ?
899 pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ?
900 "SS_OUTPUT_ENA " : "");
902 p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc);
903 p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp);
904 p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq);
905 p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io);
906 p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
907 p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem);
912 #endif /* defined(CONFIG_PROC_FS) */