]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/pcmcia/soc_common.c
Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify
[mv-sheeva.git] / drivers / pcmcia / soc_common.c
1 /*======================================================================
2
3     Common support code for the PCMCIA control functionality of
4     integrated SOCs like the SA-11x0 and PXA2xx microprocessors.
5
6     The contents of this file are subject to the Mozilla Public
7     License Version 1.1 (the "License"); you may not use this file
8     except in compliance with the License. You may obtain a copy of
9     the License at http://www.mozilla.org/MPL/
10
11     Software distributed under the License is distributed on an "AS
12     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13     implied. See the License for the specific language governing
14     rights and limitations under the License.
15
16     The initial developer of the original code is John G. Dorsey
17     <john+@cs.cmu.edu>.  Portions created by John G. Dorsey are
18     Copyright (C) 1999 John G. Dorsey.  All Rights Reserved.
19
20     Alternatively, the contents of this file may be used under the
21     terms of the GNU Public License version 2 (the "GPL"), in which
22     case the provisions of the GPL are applicable instead of the
23     above.  If you wish to allow the use of your version of this file
24     only under the terms of the GPL and not to allow others to use
25     your version of this file under the MPL, indicate your decision
26     by deleting the provisions above and replace them with the notice
27     and other provisions required by the GPL.  If you do not delete
28     the provisions above, a recipient may use your version of this
29     file under either the MPL or the GPL.
30
31 ======================================================================*/
32
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/timer.h>
39 #include <linux/mm.h>
40 #include <linux/mutex.h>
41 #include <linux/interrupt.h>
42 #include <linux/irq.h>
43 #include <linux/spinlock.h>
44 #include <linux/cpufreq.h>
45
46 #include <mach/hardware.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
49
50 #include "soc_common.h"
51
52 #ifdef CONFIG_PCMCIA_DEBUG
53
54 static int pc_debug;
55 module_param(pc_debug, int, 0644);
56
57 void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
58                       int lvl, const char *fmt, ...)
59 {
60         struct va_format vaf;
61         va_list args;
62         if (pc_debug > lvl) {
63                 va_start(args, fmt);
64
65                 vaf.fmt = fmt;
66                 vaf.va = &args;
67
68                 printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf);
69
70                 va_end(args);
71         }
72 }
73 EXPORT_SYMBOL(soc_pcmcia_debug);
74
75 #endif
76
77 #define to_soc_pcmcia_socket(x) container_of(x, struct soc_pcmcia_socket, socket)
78
79 static unsigned short
80 calc_speed(unsigned short *spds, int num, unsigned short dflt)
81 {
82         unsigned short speed = 0;
83         int i;
84
85         for (i = 0; i < num; i++)
86                 if (speed < spds[i])
87                         speed = spds[i];
88         if (speed == 0)
89                 speed = dflt;
90
91         return speed;
92 }
93
94 void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing)
95 {
96         timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
97         timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
98         timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
99 }
100 EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
101
102 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
103 {
104         struct pcmcia_state state;
105         unsigned int stat;
106
107         memset(&state, 0, sizeof(struct pcmcia_state));
108
109         skt->ops->socket_state(skt, &state);
110
111         stat = state.detect  ? SS_DETECT : 0;
112         stat |= state.ready  ? SS_READY  : 0;
113         stat |= state.wrprot ? SS_WRPROT : 0;
114         stat |= state.vs_3v  ? SS_3VCARD : 0;
115         stat |= state.vs_Xv  ? SS_XVCARD : 0;
116
117         /* The power status of individual sockets is not available
118          * explicitly from the hardware, so we just remember the state
119          * and regurgitate it upon request:
120          */
121         stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
122
123         if (skt->cs_state.flags & SS_IOCARD)
124                 stat |= state.bvd1 ? SS_STSCHG : 0;
125         else {
126                 if (state.bvd1 == 0)
127                         stat |= SS_BATDEAD;
128                 else if (state.bvd2 == 0)
129                         stat |= SS_BATWARN;
130         }
131         return stat;
132 }
133
134 /*
135  * soc_common_pcmcia_config_skt
136  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137  *
138  * Convert PCMCIA socket state to our socket configure structure.
139  */
140 static int
141 soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state)
142 {
143         int ret;
144
145         ret = skt->ops->configure_socket(skt, state);
146         if (ret == 0) {
147                 /*
148                  * This really needs a better solution.  The IRQ
149                  * may or may not be claimed by the driver.
150                  */
151                 if (skt->irq_state != 1 && state->io_irq) {
152                         skt->irq_state = 1;
153                         set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
154                 } else if (skt->irq_state == 1 && state->io_irq == 0) {
155                         skt->irq_state = 0;
156                         set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
157                 }
158
159                 skt->cs_state = *state;
160         }
161
162         if (ret < 0)
163                 printk(KERN_ERR "soc_common_pcmcia: unable to configure "
164                        "socket %d\n", skt->nr);
165
166         return ret;
167 }
168
169 /* soc_common_pcmcia_sock_init()
170  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171  *
172  * (Re-)Initialise the socket, turning on status interrupts
173  * and PCMCIA bus.  This must wait for power to stabilise
174  * so that the card status signals report correctly.
175  *
176  * Returns: 0
177  */
178 static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
179 {
180         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
181
182         debug(skt, 2, "initializing socket\n");
183
184         skt->ops->socket_init(skt);
185         return 0;
186 }
187
188
189 /*
190  * soc_common_pcmcia_suspend()
191  * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
192  *
193  * Remove power on the socket, disable IRQs from the card.
194  * Turn off status interrupts, and disable the PCMCIA bus.
195  *
196  * Returns: 0
197  */
198 static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
199 {
200         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
201
202         debug(skt, 2, "suspending socket\n");
203
204         skt->ops->socket_suspend(skt);
205
206         return 0;
207 }
208
209 static DEFINE_SPINLOCK(status_lock);
210
211 static void soc_common_check_status(struct soc_pcmcia_socket *skt)
212 {
213         unsigned int events;
214
215         debug(skt, 4, "entering PCMCIA monitoring thread\n");
216
217         do {
218                 unsigned int status;
219                 unsigned long flags;
220
221                 status = soc_common_pcmcia_skt_state(skt);
222
223                 spin_lock_irqsave(&status_lock, flags);
224                 events = (status ^ skt->status) & skt->cs_state.csc_mask;
225                 skt->status = status;
226                 spin_unlock_irqrestore(&status_lock, flags);
227
228                 debug(skt, 4, "events: %s%s%s%s%s%s\n",
229                         events == 0         ? "<NONE>"   : "",
230                         events & SS_DETECT  ? "DETECT "  : "",
231                         events & SS_READY   ? "READY "   : "",
232                         events & SS_BATDEAD ? "BATDEAD " : "",
233                         events & SS_BATWARN ? "BATWARN " : "",
234                         events & SS_STSCHG  ? "STSCHG "  : "");
235
236                 if (events)
237                         pcmcia_parse_events(&skt->socket, events);
238         } while (events);
239 }
240
241 /* Let's poll for events in addition to IRQs since IRQ only is unreliable... */
242 static void soc_common_pcmcia_poll_event(unsigned long dummy)
243 {
244         struct soc_pcmcia_socket *skt = (struct soc_pcmcia_socket *)dummy;
245         debug(skt, 4, "polling for events\n");
246
247         mod_timer(&skt->poll_timer, jiffies + SOC_PCMCIA_POLL_PERIOD);
248
249         soc_common_check_status(skt);
250 }
251
252
253 /*
254  * Service routine for socket driver interrupts (requested by the
255  * low-level PCMCIA init() operation via soc_common_pcmcia_thread()).
256  * The actual interrupt-servicing work is performed by
257  * soc_common_pcmcia_thread(), largely because the Card Services event-
258  * handling code performs scheduling operations which cannot be
259  * executed from within an interrupt context.
260  */
261 static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
262 {
263         struct soc_pcmcia_socket *skt = dev;
264
265         debug(skt, 3, "servicing IRQ %d\n", irq);
266
267         soc_common_check_status(skt);
268
269         return IRQ_HANDLED;
270 }
271
272
273 /*
274  *  Implements the get_status() operation for the in-kernel PCMCIA
275  * service (formerly SS_GetStatus in Card Services). Essentially just
276  * fills in bits in `status' according to internal driver state or
277  * the value of the voltage detect chipselect register.
278  *
279  * As a debugging note, during card startup, the PCMCIA core issues
280  * three set_socket() commands in a row the first with RESET deasserted,
281  * the second with RESET asserted, and the last with RESET deasserted
282  * again. Following the third set_socket(), a get_status() command will
283  * be issued. The kernel is looking for the SS_READY flag (see
284  * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
285  *
286  * Returns: 0
287  */
288 static int
289 soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
290 {
291         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
292
293         skt->status = soc_common_pcmcia_skt_state(skt);
294         *status = skt->status;
295
296         return 0;
297 }
298
299
300 /*
301  * Implements the set_socket() operation for the in-kernel PCMCIA
302  * service (formerly SS_SetSocket in Card Services). We more or
303  * less punt all of this work and let the kernel handle the details
304  * of power configuration, reset, &c. We also record the value of
305  * `state' in order to regurgitate it to the PCMCIA core later.
306  */
307 static int
308 soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
309 {
310         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
311
312         debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n",
313                         (state->csc_mask==0)?"<NONE> ":"",
314                         (state->csc_mask&SS_DETECT)?"DETECT ":"",
315                         (state->csc_mask&SS_READY)?"READY ":"",
316                         (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
317                         (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
318                         (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
319                         (state->flags==0)?"<NONE> ":"",
320                         (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
321                         (state->flags&SS_IOCARD)?"IOCARD ":"",
322                         (state->flags&SS_RESET)?"RESET ":"",
323                         (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
324                         (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
325                         state->Vcc, state->Vpp, state->io_irq);
326
327         return soc_common_pcmcia_config_skt(skt, state);
328 }
329
330
331 /*
332  * Implements the set_io_map() operation for the in-kernel PCMCIA
333  * service (formerly SS_SetIOMap in Card Services). We configure
334  * the map speed as requested, but override the address ranges
335  * supplied by Card Services.
336  *
337  * Returns: 0 on success, -1 on error
338  */
339 static int
340 soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
341 {
342         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
343         unsigned short speed = map->speed;
344
345         debug(skt, 2, "map %u  speed %u start 0x%08llx stop 0x%08llx\n",
346                 map->map, map->speed, (unsigned long long)map->start,
347                 (unsigned long long)map->stop);
348         debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
349                 (map->flags==0)?"<NONE>":"",
350                 (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
351                 (map->flags&MAP_16BIT)?"16BIT ":"",
352                 (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
353                 (map->flags&MAP_0WS)?"0WS ":"",
354                 (map->flags&MAP_WRPROT)?"WRPROT ":"",
355                 (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
356                 (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
357
358         if (map->map >= MAX_IO_WIN) {
359                 printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
360                        map->map);
361                 return -1;
362         }
363
364         if (map->flags & MAP_ACTIVE) {
365                 if (speed == 0)
366                         speed = SOC_PCMCIA_IO_ACCESS;
367         } else {
368                 speed = 0;
369         }
370
371         skt->spd_io[map->map] = speed;
372         skt->ops->set_timing(skt);
373
374         if (map->stop == 1)
375                 map->stop = PAGE_SIZE-1;
376
377         map->stop -= map->start;
378         map->stop += skt->socket.io_offset;
379         map->start = skt->socket.io_offset;
380
381         return 0;
382 }
383
384
385 /*
386  * Implements the set_mem_map() operation for the in-kernel PCMCIA
387  * service (formerly SS_SetMemMap in Card Services). We configure
388  * the map speed as requested, but override the address ranges
389  * supplied by Card Services.
390  *
391  * Returns: 0 on success, -ERRNO on error
392  */
393 static int
394 soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
395 {
396         struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
397         struct resource *res;
398         unsigned short speed = map->speed;
399
400         debug(skt, 2, "map %u speed %u card_start %08x\n",
401                 map->map, map->speed, map->card_start);
402         debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
403                 (map->flags==0)?"<NONE>":"",
404                 (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
405                 (map->flags&MAP_16BIT)?"16BIT ":"",
406                 (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
407                 (map->flags&MAP_0WS)?"0WS ":"",
408                 (map->flags&MAP_WRPROT)?"WRPROT ":"",
409                 (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
410                 (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
411
412         if (map->map >= MAX_WIN)
413                 return -EINVAL;
414
415         if (map->flags & MAP_ACTIVE) {
416                 if (speed == 0)
417                         speed = 300;
418         } else {
419                 speed = 0;
420         }
421
422         if (map->flags & MAP_ATTRIB) {
423                 res = &skt->res_attr;
424                 skt->spd_attr[map->map] = speed;
425                 skt->spd_mem[map->map] = 0;
426         } else {
427                 res = &skt->res_mem;
428                 skt->spd_attr[map->map] = 0;
429                 skt->spd_mem[map->map] = speed;
430         }
431
432         skt->ops->set_timing(skt);
433
434         map->static_start = res->start + map->card_start;
435
436         return 0;
437 }
438
439 struct bittbl {
440         unsigned int mask;
441         const char *name;
442 };
443
444 static struct bittbl status_bits[] = {
445         { SS_WRPROT,            "SS_WRPROT"     },
446         { SS_BATDEAD,           "SS_BATDEAD"    },
447         { SS_BATWARN,           "SS_BATWARN"    },
448         { SS_READY,             "SS_READY"      },
449         { SS_DETECT,            "SS_DETECT"     },
450         { SS_POWERON,           "SS_POWERON"    },
451         { SS_STSCHG,            "SS_STSCHG"     },
452         { SS_3VCARD,            "SS_3VCARD"     },
453         { SS_XVCARD,            "SS_XVCARD"     },
454 };
455
456 static struct bittbl conf_bits[] = {
457         { SS_PWR_AUTO,          "SS_PWR_AUTO"   },
458         { SS_IOCARD,            "SS_IOCARD"     },
459         { SS_RESET,             "SS_RESET"      },
460         { SS_DMA_MODE,          "SS_DMA_MODE"   },
461         { SS_SPKR_ENA,          "SS_SPKR_ENA"   },
462         { SS_OUTPUT_ENA,        "SS_OUTPUT_ENA" },
463 };
464
465 static void
466 dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz)
467 {
468         char *b = *p;
469         int i;
470
471         b += sprintf(b, "%-9s:", prefix);
472         for (i = 0; i < sz; i++)
473                 if (val & bits[i].mask)
474                         b += sprintf(b, " %s", bits[i].name);
475         *b++ = '\n';
476         *p = b;
477 }
478
479 /*
480  * Implements the /sys/class/pcmcia_socket/??/status file.
481  *
482  * Returns: the number of characters added to the buffer
483  */
484 static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
485 {
486         struct soc_pcmcia_socket *skt =
487                 container_of(dev, struct soc_pcmcia_socket, socket.dev);
488         char *p = buf;
489
490         p+=sprintf(p, "slot     : %d\n", skt->nr);
491
492         dump_bits(&p, "status", skt->status,
493                   status_bits, ARRAY_SIZE(status_bits));
494         dump_bits(&p, "csc_mask", skt->cs_state.csc_mask,
495                   status_bits, ARRAY_SIZE(status_bits));
496         dump_bits(&p, "cs_flags", skt->cs_state.flags,
497                   conf_bits, ARRAY_SIZE(conf_bits));
498
499         p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
500         p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
501         p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
502                 skt->socket.pci_irq);
503         if (skt->ops->show_timing)
504                 p+=skt->ops->show_timing(skt, p);
505
506         return p-buf;
507 }
508 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
509
510
511 static struct pccard_operations soc_common_pcmcia_operations = {
512         .init                   = soc_common_pcmcia_sock_init,
513         .suspend                = soc_common_pcmcia_suspend,
514         .get_status             = soc_common_pcmcia_get_status,
515         .set_socket             = soc_common_pcmcia_set_socket,
516         .set_io_map             = soc_common_pcmcia_set_io_map,
517         .set_mem_map            = soc_common_pcmcia_set_mem_map,
518 };
519
520
521 int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
522                             struct pcmcia_irqs *irqs, int nr)
523 {
524         int i, res = 0;
525
526         for (i = 0; i < nr; i++) {
527                 if (irqs[i].sock != skt->nr)
528                         continue;
529                 res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
530                                   IRQF_DISABLED, irqs[i].str, skt);
531                 if (res)
532                         break;
533                 set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
534         }
535
536         if (res) {
537                 printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
538                         irqs[i].irq, res);
539
540                 while (i--)
541                         if (irqs[i].sock == skt->nr)
542                                 free_irq(irqs[i].irq, skt);
543         }
544         return res;
545 }
546 EXPORT_SYMBOL(soc_pcmcia_request_irqs);
547
548 void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
549                           struct pcmcia_irqs *irqs, int nr)
550 {
551         int i;
552
553         for (i = 0; i < nr; i++)
554                 if (irqs[i].sock == skt->nr)
555                         free_irq(irqs[i].irq, skt);
556 }
557 EXPORT_SYMBOL(soc_pcmcia_free_irqs);
558
559 void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
560                              struct pcmcia_irqs *irqs, int nr)
561 {
562         int i;
563
564         for (i = 0; i < nr; i++)
565                 if (irqs[i].sock == skt->nr)
566                         set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
567 }
568 EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
569
570 void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
571                             struct pcmcia_irqs *irqs, int nr)
572 {
573         int i;
574
575         for (i = 0; i < nr; i++)
576                 if (irqs[i].sock == skt->nr) {
577                         set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
578                         set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
579                 }
580 }
581 EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
582
583
584 static LIST_HEAD(soc_pcmcia_sockets);
585 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
586
587 #ifdef CONFIG_CPU_FREQ
588 static int
589 soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
590 {
591         struct soc_pcmcia_socket *skt;
592         struct cpufreq_freqs *freqs = data;
593         int ret = 0;
594
595         mutex_lock(&soc_pcmcia_sockets_lock);
596         list_for_each_entry(skt, &soc_pcmcia_sockets, node)
597                 if ( skt->ops->frequency_change )
598                         ret += skt->ops->frequency_change(skt, val, freqs);
599         mutex_unlock(&soc_pcmcia_sockets_lock);
600
601         return ret;
602 }
603
604 static struct notifier_block soc_pcmcia_notifier_block = {
605         .notifier_call  = soc_pcmcia_notifier
606 };
607
608 static int soc_pcmcia_cpufreq_register(void)
609 {
610         int ret;
611
612         ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
613                                         CPUFREQ_TRANSITION_NOTIFIER);
614         if (ret < 0)
615                 printk(KERN_ERR "Unable to register CPU frequency change "
616                                 "notifier for PCMCIA (%d)\n", ret);
617         return ret;
618 }
619 fs_initcall(soc_pcmcia_cpufreq_register);
620
621 static void soc_pcmcia_cpufreq_unregister(void)
622 {
623         cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
624 }
625 module_exit(soc_pcmcia_cpufreq_unregister);
626
627 #endif
628
629 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
630 {
631         mutex_lock(&soc_pcmcia_sockets_lock);
632         del_timer_sync(&skt->poll_timer);
633
634         pcmcia_unregister_socket(&skt->socket);
635
636         skt->ops->hw_shutdown(skt);
637
638         soc_common_pcmcia_config_skt(skt, &dead_socket);
639
640         list_del(&skt->node);
641         mutex_unlock(&soc_pcmcia_sockets_lock);
642
643         iounmap(skt->virt_io);
644         skt->virt_io = NULL;
645         release_resource(&skt->res_attr);
646         release_resource(&skt->res_mem);
647         release_resource(&skt->res_io);
648         release_resource(&skt->res_skt);
649 }
650 EXPORT_SYMBOL(soc_pcmcia_remove_one);
651
652 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
653 {
654         int ret;
655
656         init_timer(&skt->poll_timer);
657         skt->poll_timer.function = soc_common_pcmcia_poll_event;
658         skt->poll_timer.data = (unsigned long)skt;
659         skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
660
661         ret = request_resource(&iomem_resource, &skt->res_skt);
662         if (ret)
663                 goto out_err_1;
664
665         ret = request_resource(&skt->res_skt, &skt->res_io);
666         if (ret)
667                 goto out_err_2;
668
669         ret = request_resource(&skt->res_skt, &skt->res_mem);
670         if (ret)
671                 goto out_err_3;
672
673         ret = request_resource(&skt->res_skt, &skt->res_attr);
674         if (ret)
675                 goto out_err_4;
676
677         skt->virt_io = ioremap(skt->res_io.start, 0x10000);
678         if (skt->virt_io == NULL) {
679                 ret = -ENOMEM;
680                 goto out_err_5;
681         }
682
683         mutex_lock(&soc_pcmcia_sockets_lock);
684
685         list_add(&skt->node, &soc_pcmcia_sockets);
686
687         /*
688          * We initialize default socket timing here, because
689          * we are not guaranteed to see a SetIOMap operation at
690          * runtime.
691          */
692         skt->ops->set_timing(skt);
693
694         ret = skt->ops->hw_init(skt);
695         if (ret)
696                 goto out_err_6;
697
698         skt->socket.ops = &soc_common_pcmcia_operations;
699         skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
700         skt->socket.resource_ops = &pccard_static_ops;
701         skt->socket.irq_mask = 0;
702         skt->socket.map_size = PAGE_SIZE;
703         skt->socket.io_offset = (unsigned long)skt->virt_io;
704
705         skt->status = soc_common_pcmcia_skt_state(skt);
706
707         ret = pcmcia_register_socket(&skt->socket);
708         if (ret)
709                 goto out_err_7;
710
711         add_timer(&skt->poll_timer);
712
713         mutex_unlock(&soc_pcmcia_sockets_lock);
714
715         ret = device_create_file(&skt->socket.dev, &dev_attr_status);
716         if (ret)
717                 goto out_err_8;
718
719         return ret;
720
721  out_err_8:
722         mutex_lock(&soc_pcmcia_sockets_lock);
723         del_timer_sync(&skt->poll_timer);
724         pcmcia_unregister_socket(&skt->socket);
725
726  out_err_7:
727         skt->ops->hw_shutdown(skt);
728  out_err_6:
729         list_del(&skt->node);
730         mutex_unlock(&soc_pcmcia_sockets_lock);
731         iounmap(skt->virt_io);
732  out_err_5:
733         release_resource(&skt->res_attr);
734  out_err_4:
735         release_resource(&skt->res_mem);
736  out_err_3:
737         release_resource(&skt->res_io);
738  out_err_2:
739         release_resource(&skt->res_skt);
740  out_err_1:
741
742         return ret;
743 }
744 EXPORT_SYMBOL(soc_pcmcia_add_one);
745
746 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
747 MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
748 MODULE_LICENSE("Dual MPL/GPL");